当空白=True 并发布空字符串时,Django IntegerField 忽略指定的默认值

use*_*384 4 django django-models django-forms

考虑以下模型字段:

myfield = models.IntegerField(_('My field'), blank=True, default=0)
Run Code Online (Sandbox Code Playgroud)

如果帖子中完全省略了 myfield,则默认 ModelForm 实现会正确使用默认值。但是,如果为该字段发布空字符串,则字段值将保持为 None,并且 postgres 会失败,并在非空字段上出现 IntegrityError:

IntegrityError:列“myfield”中的空值违反了非空约束

问题:如何在 myfield 值不存在或存在但为空字符串的两种情况下强制执行默认值?

让我认为这是一个 django bug 的是 ModelForm 验证成功通过,但无法保存表单。尽管从语义上来说字段声明是正确的,但如果空字符串不是字段的有效值,则表单验证应该失败,否则应确保为字段值分配正确的整数。

实现一个干净的方法来用默认值替换空字符串是可能的,但相当丑陋。寻找更好的方法来做到这一点:

sol*_*oke 6

这显然是预期的行为,并且在此 wiki 页面上对其进行了引用。

default是创建新对象时用于字段的默认值,并且没有为该字段指定任何类型的值。当在表单中传递空值时,它不用于填充字段。

blank指定表单中是否允许使用空值。但它不控制该空值在数据库中是否有效。

因此,default这里不会执行您想要的操作,并且当您在表单中传递空字符串时,它将作为空值传递到数据库。

您有两个选择:

  1. 设置null=True字段以允许空值(但这在语义上可能没有意义)。

  2. 重写clean模型上的方法,在保存空值之前将其转换为 0,例如:

    def clean(self):
        if self.myfield is None:
            self.myfield = 0
    
    Run Code Online (Sandbox Code Playgroud)