【Django】django.core.exceptions.FieldError: Unknown field(s) () specified for
【Django】django.core.exceptions.FieldError: Unknown field(s) () specified for
なかなか悩みました。直訳すれば「知らないフィールド操作しようとしてるよ」って事なのです。
でもそこはDjango初心者、怪しい所を見ていても気づかないというね。
と言う事で、今後の為の整理整頓です。
まずエラーが出たらエラー直前の動きを確認する
どういうルートでプログラムが動いたかを確認すれば『修正場所』が解ります。
今回のエラー発生直前の流れはこんな感じでした。
1 2 3 4 |
File "/code/company/views.py", line 7, in <module> from .forms import InquiryForm File "/code/company/forms.py", line 45, in <module> class CompanyCreateForm(forms.ModelForm): |
動きを翻訳してみるとこんな感じです。
- company/viewsの7行目にあるInquiryFormを調べるため、company/forms.pyを読みに行く。
- forms.pyの45行目にあるCompanyCreateFormを読みに行く。
- で、読もうとしたらCompanyCreateFormに書いてあるフィールドが無いんですけど…。
と言う事は、怪しいのはテーブル構成を管理してるModelsって事になります。
記載していた誤ったmodels.py と正しいmodels.py
まずは正しいものから。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from django.db import models class Company(models.Model): """企業情報モデル""" name = models.CharField(verbose_name='企業名', max_length=200, blank=False) postal_code = models.CharField(verbose_name='郵便番号', max_length=7, blank=False) prefecture = models.CharField(verbose_name='県名', max_length=10, blank=True) municipalities = models.CharField(verbose_name='市町村', max_length=30, blank=True) details = models.CharField(verbose_name='番地詳細', max_length=50, blank=True) buildings = models.CharField(verbose_name='建物名', max_length=150, blank=True) tel_number = models.CharField(verbose_name='電話番号', max_length=15, blank=False) fax_number = models.CharField(verbose_name='FAX番号', max_length=15, blank=True) email = models.EmailField(verbose_name='代表メール', blank=True) website = models.URLField(verbose_name='ホームページ', blank=True) created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) class Meta: verbose_name_plural = 'Company' def __str__(self): return self.name |
こちら、間違えていたものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from django.db import models class Company(models.Model): """企業情報モデル""" name = models.CharField(verbose_name='企業名', max_length=200, blank=False), postal_code = models.CharField(verbose_name='郵便番号', max_length=7, blank=False), prefecture = models.CharField(verbose_name='県名', max_length=10, blank=True), municipalities = models.CharField(verbose_name='市町村', max_length=30, blank=True), details = models.CharField(verbose_name='番地詳細', max_length=50, blank=True), buildings = models.CharField(verbose_name='建物名', max_length=150, blank=True), tel_number = models.CharField(verbose_name='電話番号', max_length=15,blank=False), fax_number = models.CharField(verbose_name='FAX番号', max_length=15, blank=True), email = models.EmailField(verbose_name='代表メール', blank=True) website = models.URLField(verbose_name='ホームページ', blank=True) created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) class Meta: verbose_name_plural = 'Company' def __str__(self): return self.name |
NG箇所は各行最後の【 , (カンマ)】。こいつがあったからテーブル構成がおかしくなってたんですね。
マイグレーション用ファイルを作成する
1 |
python manage.py makemigrations |
そしてマイグレーション実行。
1 |
python manage.py migrate |
ん?またエラーが出ました。
1 |
You are trying to add a non-nullable field '' to company without a default; we can't do that (the database needs something to populate existing rows). |
NULLを許可してないのに blank=False するなと怒られている?
name = models.CharField(verbose_name=’企業名’, max_length=200, blank=False)
どうやらこいつがNGの様子。Laravelのマイグレーションって空のテーブルを作る形だったから全く意識してなかったけどDjangoではここら辺しっかりしてないとダメみたいです。
1 2 3 4 5 |
Please select a fix: 1) Provide a one-off default now (will be set on all existing rows with a null value for this column) 2) Quit, and let me add a default in models.py Select an option: |
1を選択するとPython が起動してゴニョゴニョできます。
2を選択するとマイグレーションが終了します。
You are trying to add a non-nullable field ” to company without a defaultの解決方法
方法は2つです。
- blankを外す ※エラーの元となる構成を積み込まない
- default値を設定する
defaultを設定する場合、次のように書きます。
1 2 3 |
(前略) prefecture = models.CharField(verbose_name='県名', max_length=10, default='新潟県') municipalities = models.CharField(verbose_name='市町村', max_length=30, null=True) |
defult=’ほげ’ でデフォルトに固定値が入り、null=TrueとするとデフォルトにNULLが設定されます。
デフォルトを構成して python manage.py migrate すればテーブル作成完了です。
郵便番号とか電話番号のバリデーションで数値以外を記載できない様にする
1 2 |
postal_code_regex = RegexValidator(regex=r'^[0-9]+$', message = ("Postal Code must be entered in the format: '1234567'. Up to 7 digits allowed.")) postal_code = models.CharField(validators=[postal_code_regex], max_length=7, verbose_name='郵便番号', null=True) |
こんな形で構成してあげるとValidationを一緒に記載できるそうです。
まとめ
models.pyのカンマ、なんで気付かなかったのか…。
Laravelのマイグレーションは行末に【;】を付けるから目が違和感を察知しなかったんだろうなぁ。
反省です。
-
前の記事
【Docker】Django×MySQL×Nginxの selenium入りDockerfile構成 2020.11.21
-
次の記事
【Django】Forms.pyって何!? バリデーション構築で混乱してきたので整理してみた 2020.11.27
コメントを残す