Django:The Model名 could not be changed because the data didn’t validate.エラーの原因と対策
Django:The Model名 could not be changed because the data didn’t validate.エラーの原因と対策
これは私がCRUD作成の一番最初に苦しめられたエラーです。
POSTされた値のカラム名がForm / ModelFormと合致していないときに発生します。
エラー発生原は様々ですが、私の場合は下の組合せが原因でした。
- Models.py 内で【models.DateField(null=True, default=None)】としたフィールドに対し何も入れずにPOSTした。
- Models.py 内で【models.IntegerField(null=True, default=None)】としたフィールドに対し何も入れずにPOSTした。
- Models.py 内で【RegexValidator(regex=r’^[0-9]+$’)】としたフィールドに対し何も入れずにPOSTした。
- POSTしたリレーションカラム名がModel内の名称と違っていた
POSTされた値が文字列ではない時やリレーションを張っているカラムが存在する時、このエラーの発生率は高まります。
なにも記載しないでPOSTした場合、[ ’’ ]や[ ‘None’ ] がPOSTされている
Validateのエラーはこのような空データが原因となっている事が多いようです。
回避する手段については以前も少し触れましたが2つあります。
- Form / ModelFormのバリデーションを使わない。
- POSTされた[ ” ] や [ ‘None ] を置換してからForm / ModelFormのバリデーションにかける
最適解としては外部関数としてlibrary.pyなどに下記コードを登録し利用したうえでバリデーションに掛ける事です。
1 2 3 4 5 6 7 |
def BlankChanger(data): #''や’None’でPOSTされた値をNoneに置き換える copy_dict = data.copy() for cd in copy_dict: if (cd == '')or(cd == 'None'): cd = None return copy_dict |
上に記載した私が経験した原因の1~3はこれでクリアできます。
POSTしたリレーションカラム名ってなに?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from django.db import models from accounts.models import CustomUser class Customerdatas(models.Model): customer = models.ForeignKey(CustomUser, on_delete=models.CASCADE, verbose_name='ユーザーID') birthday = models.DateField(verbose_name="生年月日", blank=False, auto_now=False, default=None) lasteducation = models.CharField(verbose_name="最終学歴", max_length=100, blank=True, null=True, default=None) graduationdate = models.DateField(verbose_name='卒業年月', blank=True, null=True, default=None) prmessaeg = models.TextField(verbose_name='PR文', blank=True, null=True, default=None) created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) class Meta: verbose_name_plural = 'Customerdatas' def __str__(self): return self.CustomUser.last_name + ' ' + self.CustomUser.first_name |
この6行目【customer = models.ForeignKey(CustomUser, on_delete=models.CASCADE…)】がリレーションのテーブルです。このリレーションは今『1対多』で組んでいます。
注目はcustomer_idではなくcustomerで登録している事です。
LaravelではSQLテーブルの姿をそのまま記載するのでカラムの呼び出しは【customer_id】とすることが基本ですが、Djangoは [ _id ]を付ける作業を勝手に行ってくれます。
1 |
customer_id = models.ForeignKey(CustomUser, on_delete=models.CASCADE, verbose_name='ユーザーID') |
なので、このようにmodels.pyに書いた場合、migrationするとMySQLには【customer_id_id】というカラムが出来上がります。
ModelFormを使う場合、Modelに登録した名称が正
MySQL内のカラム名がcustomer_idになっていてもcustomeruser_idになっていても、Modelに存在していなければバリデーションエラーが発生します。
models.pyにcustomer と記載しているならTemplate.htmlでは【<imput name=’customer’ …>】でPOSTしてあげましょう。
まとめ
ここら辺のエラーは多分みんなが通る道なのだろうなと思います。
慣れればなんてことはないんですけどね。
-
前の記事
Django:this querydict instance is immutable request.data エラーの原因と対策 2021.02.26
-
次の記事
CloudWorksってカオスなオーダーとワーカー多くない? 2021.03.02
コメントを残す