跟踪:在django中缺少所需的Charfield Modelform保存为空字符串,不会引起错误 [英] Followup : missing required Charfield in django Modelform is saved as empty string and do not raise an error

查看:252
本文介绍了跟踪:在django中缺少所需的Charfield Modelform保存为空字符串,不会引起错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我尝试在Django 1.10中保存不完整的模型实例,我会期望Django引发错误。这似乎不是这样的。

If I try to save incomplete model instance in Django 1.10, I would expect Django to raise an error. It does not seem to be the case.

models.py:

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在存储之前未设置其中一个字段时发生错误。

So I have two fields not allowed to be empty (default behavior, NOT NULL restriction is applied by Django at MySQL table creation). I expect Django to rase an error if one of the fields is not set before storing.

但是,当我创建一个不完整的实例时,数据被存储很好: / p>

However, when I create an incomplete instance, the data is stored just fine:

>>> 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 ,则会引发错误:

I would have expected Django to raise an error. If I force ch2 to None, however, it raises an error:

>>> 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不起作用

Explanation: Django is not raising an error as default behavior in this simple case because in SQL empty string "" is not equivalent to NULL, as stated in Django model blank=False does not work?

现在,如果我们看看ModelForm行为,django似乎有一个不一致doc:

Now, if we look at ModelForm behavior, there seem to be a inconsistency in django doc:

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


Django将防止任何尝试保存不完整的模型,因此如果模型不允许缺少的字段为空,并且不为缺少的字段提供默认值,任何尝试保存()缺少字段的ModelForm将失败。为了避免这种失败,您必须使用缺少但必需的字段的初始值实例化模型:(...)

Django will prevent any attempt to save an incomplete model, so if the model does not allow the missing fields to be empty, and does not provide a default value for the missing fields, any attempt to save() a ModelForm with missing fields will fail. To avoid this failure, you must instantiate your model with initial values for the missing, but required fields:(…)

一个modelForm应该如果没有默认值,则不会保存缺少的字段。

a modelForm should not be saved with a missing field if there is no default value.

所以使用这个ModelForm:

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

只有一个字段的表单 ch1 被生成。

So with this ModelForm: class EssaiModelForm(forms.ModelForm): class Meta: model = Essai fields = ['ch1'] A form with only one field ch1 is generated.


  • 如果 ch1 保留为空,则 EssaiModelFormInstance.is_valid()如预期。

  • 如果 ch1 包含一个值,即使 ch2 是仍然失踪然后EssaiModelFormInstance.save()成功,这与django文档中所声明的相反。 ch2 是空字符串,因此与SQL要求( NOT NULL )兼容。

  • If ch1 is left empty, the validation fails at EssaiModelFormInstance.is_valid() as expected.
  • If ch1 contains a value, the validation succeeds even though ch2 is still missing. Then the EssaiModelFormInstance.save() succeeds, contrary to what is claimed in django documentation. ch2 is empty string and thus is compatible with SQL requirements (NOT NULL).

所以似乎Charfield的默认默认值为空字符串不是在表单验证中接受,但在save()验证中接受。这可能需要在文档中进行说明。

So it seems that there is a default default value empty string "" for Charfield that is not accepted in form validation but that is accepted in save() validation. This may require clarification in the documentation.

推荐答案

模型和它的形式有一个显着的差异。 Model.save()不执行验证。所以如果它失败,那么可能会引发一个数据库级别的IntegrityError。为了减少数据库层故障的风险,需要调用ModelForm_clean(),它也由ModelForm完成,如 django的验证对象

There is a slightly notable difference in model and it's forms. Model.save() performs no validation. So if it fails then probably it raises a database level IntegrityError. For reducing risks of failure at database layer one need to call Model.full_clean() which is also done by ModelForm as documented here in django's validating objects.

在我看来,我期望从django,ModelForms旨在验证和保存客户端输入的数据。以编程方式实例化的模型在保存到数据库之前应遵循相同的控件。

In my opinion, I expect from django that ModelForms are meant to validate and save data entered by client. Model instantiated programmatically should follow the same control before saving into database.

这篇关于跟踪:在django中缺少所需的Charfield Modelform保存为空字符串,不会引起错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆