首页 > 解决方案 > 即使需要字段,也会创建对象

问题描述

#models.py

class Mymodel(models.Model):
    name = models.CharField(max_length=100,null=False,blank=False)
    email = models.EmailField(max_length=100,null=False,blank=False)
    password = models.CharField(max_length=120,null=False,blank=False)
    email_notification = models.BooleanField()




#views.py

obj=MyModel.objects.create(name="ok",password="dsfdsfdsfdsfsfds",email_notification=1)

即使电子邮件是必填字段,当我在管理面板中看到时,也会创建对象。可能是什么问题,为什么要创建对象,即使电子邮件字段是强制性的?此外,如果我进入管理面板并打开该对象并单击保存,那么它会引发该电子邮件是必需的

标签: pythondjangodjango-models

解决方案


注意:您不必在字段中提供 null=False,blank=False 因为这些是默认使用的值。(参见DjangoField __int__签名。)。

def __init__(self, verbose_name=None, name=None, primary_key=False,
                 max_length=None, unique=False, blank=False, null=False,
                 db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
                 serialize=True, unique_for_date=None, unique_for_month=None,
                 unique_for_year=None, choices=None, help_text='', db_column=None,
                 db_tablespace=None, auto_created=False, validators=(),
                 error_messages=None):

默认情况下,数据库中的所有字段都是使用NOT NULL约束创建的。如果您null=True为特定字段设置,那么 djangoNULL会在您的数据库中的列上设置。 它是 Python关键字的数据库等价物。None

null带参数的示例

假设我有以下内容Mymodel并将my_app字段设置emailnull=True.

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(max_length=100, null=True)
    password = models.CharField(max_length=120)
    email_notification = models.BooleanField()

在壳牌中,

>> from my_app.models import MyModel

>> new = MyModel.objects.create(name="ok",
                                password="dsfdsfdsfdsfsfds",
                                email_notification=1)
>> new.email == None
>> True # As you can see Django sets db value 
        # as NULL and when we query the data it converts back to Python `None` object.

null没有参数的例子

假设我的Mymodel. 中有以下内容my_app(记住默认情况下nullFalse

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(max_length=100)
    password = models.CharField(max_length=120)
    email_notification = models.BooleanField()

在壳牌中,

>> from my_app.models import MyModel
>> new_obj = MyModel.objects.create(name="test",
                                password="test",
                                email_notification=1)
>> new_obj.email == ''
>> True

即,DjangoCharFieldTextField默认值作为空字符串 ( '')存储在数据库中。换句话说,如果你创建了一个对象而没有在后台为 a CharField(或 a TextField)提供值,Django 会调用该get_default方法并返回''(仅在这种情况下)。该值将存储在数据库中。

以下是get_default方法的源代码。

def get_default(self):
    """Return the default value for this field."""
    return self._get_default()

@cached_property
def _get_default(self):
    if self.has_default():
        if callable(self.default):
            return self.default
        return lambda: self.default

    if not self.empty_strings_allowed or self.null and not connection.features.interprets_empty_strings_as_nulls:
        return return_None
    return str  # return empty string

让我们回答你的问题:

为什么要创建对象,即使电子邮件字段是强制性的?

答案是因此在数据库中创建对象时将使用默认值EmailField的实例。这就是为什么你没有得到.CharField''django.db.utils.IntegrityError

>> new_obj = Mymodel.objects.create(name='tes1t', password='test1', email_notification=1)
>>> new_obj.email
''

此外,如果我转到管理面板并打开该对象并单击保存,那么它会引发一个错误,表明需要电子邮件

记住blank不同于null. null纯粹与数据库相关,而blank与验证相关。因此,当您直接在 Python 代码中创建对象,或自己执行原始 SQL 时,您实际上绕过了 Django 的所有输入验证。但在管理中,Django 正在通过模型表单验证输入。由于在您的情况下blank设置为 False(不允许空白),模型表单将引发Email is required错误。

这是blank参数的相关 Django 文档。

字段空白

如果为 True,则该字段允许为空。默认为假。请注意,这与 null 不同。null 纯粹与数据库相关,而空白与验证相关。如果一个字段有空白=真,表单验证将允许输入一个空值。如果某个字段的空白=False,则该字段将是必需的。

其他资源


推荐阅读