簡體   English   中英

后續行動:在Django Modelform中缺少必需的Charfield被保存為空字符串,並且不會引發錯誤

[英]Followup : missing required Charfield in django Modelform is saved as empty string and do not raise an error

如果我嘗試在Django 1.10中保存不完整的模型實例,那么我會期望Django引發錯誤。 似乎並非如此。

models.py:

from django.db import models

class Essai(models.Model):
    ch1 = models.CharField(max_length=100, blank=False)
    ch2 = models.CharField(max_length=100, blank=False)

因此,我有兩個字段不允許為空(默認行為,Django在MySQL表創建時應用了NOT NULL限制)。 我希望Django在存儲前未設置任何字段的情況下引發錯誤。

但是,當我創建一個不完整的實例時,數據存儲就很好了:

>>> from test.models import Essai
>>> bouh = Essai()
>>> bouh.ch1 = "some content for ch1"
>>> bouh.save()
>>> bouh.id
9
>>> bouh.ch1
'some content for ch1'
>>> bouh.ch2
''
>>> 

我本來希望Django引發錯誤。 如果我將ch2強制為None ,則會引發錯誤:

>>> bouh = Essai()
>>> bouh.ch1 = "some content for ch1"
>>> bouh.ch2 = None
>>> bouh.save()
Traceback (most recent call last):
  (...)
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: test_essai.ch2
>>> bouh.id
>>> bouh.ch1
'some content for ch1'
>>> bouh.ch2
>>>

說明:在這種簡單情況下,Django不會引發錯誤作為默認行為,因為在SQL中,空字符串""不等於NULL,如Django模型中所述, blank = False不起作用?

現在,如果我們看一下ModelForm的行為,django doc中似乎有一個不一致之處:

根據: https : //docs.djangoproject.com/en/1.10/topics/forms/modelforms/#selecting-the-fields-to-use

Django會阻止保存不完整模型的任何嘗試,因此,如果模型不允許丟失的字段為空,並且不為丟失的字段提供默認值,則任何嘗試保存()帶有丟失字段的ModelForm的嘗試都會失敗。 為了避免這種失敗,您必須使用缺少值但必填字段的初始值實例化模型:(…)

如果沒有默認值,則不應將modelForm保存為缺少字段。

因此,使用此ModelForm: class EssaiModelForm(forms.ModelForm): class Meta: model = Essai fields = ['ch1']生成僅包含一個字段ch1表單。

  • 如果ch1保留為空,則驗證EssaiModelFormInstance.is_valid()預期在EssaiModelFormInstance.is_valid()處失敗。
  • 如果ch1包含一個值,則即使ch2仍然丟失,驗證也會成功。 然后,與Django文檔中要求的相反,EssaiModelFormInstance.save()成功。 ch2是空字符串,因此與SQL要求兼容( NOT NULL )。

因此,似乎Charfield有一個默認的默認值空字符串"" ,在表單驗證中不接受 ,但在save()驗證中可接受 這可能需要在文檔中進行說明。

由於在您的情況下始終需要兩個字段ch1ch2 ,因此您所需要做的就是修改模型,以便

from django.db import models

class Essai(models.Model):
    ch1 = models.CharField(max_length=100)
    ch2 = models.CharField(max_length=100)

並以以下形式包含字段:

class EssaiModelForm(forms.ModelForm):
class Meta:
    model = Essai
    fields = ['ch1', 'ch2']

Django會在is_valid()上針對此字段自動引發驗證錯誤

或者,如果您要禁止向這些字段輸入空字符串,則blank=False將不起作用

參考此Django-如何設置blank = False,必填= False

模型及其形式略有顯着差異。 Model.save()不執行任何驗證。 因此,如果失敗,則可能會引發數據庫級別的IntegrityError。 為了降低數據庫層發生故障的風險,需要調用Model.full_clean(),這也由ModelForm完成,如django的驗證對象中所述

我認為,django希望ModelForms用於驗證和保存客戶輸入的數據。 以編程方式實例化的模型在保存到數據庫之前應遵循相同的控制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM