即使需要字段也创建对象

时间:2018-07-03 07:31:45

标签: python django django-models

#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)

即使电子邮件是必填字段,当在管理面板中看到时也创建了对象。这可能是问题所在,即使电子邮件是必填字段,为什么也要创建对象? 另外,如果我进入管理面板并打开该对象,然后单击“保存”,则会引发电子邮件必填

2 个答案:

答案 0 :(得分:2)

注意:您不必在字段中提供null = False,blank = False,因为这些是默认使用的值。(请参见Django Field __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,则django在数据库的列中设置了NULL 这是Python的None关键字的数据库等效项。

带有null参数的示例

假设我在Mymodel中有以下my_app,并将email字段设置为null=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()

在Shell中,

>> 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。(请记住,null默认为False

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()

在Shell中,

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

即, Django CharFieldTextField的默认值作为空字符串('')存储在数据库中。换句话说,如果您在没有提供CharField(或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

让我们回答问题,

  

即使电子邮件字段是必填字段,为什么也要创建对象?

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

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

此外,如果我进入管理面板并打开该对象,然后单击“保存”,则   它提出电子邮件是必需的

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

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

  

Field.blank

     

如果为True,则该字段允许为空白。默认值为False。注意   这不同于null。 null完全与数据库有关,   而空白与验证相关。如果字段的空白为True,则表单   验证将允许输入一个空值。如果一个字段有   blank = False,必填字段。

其他资源

答案 1 :(得分:1)

django没问题,您将必须创建正确的 Django Model Form验证,以便不忽略空字符串,并且会为空白字段引发错误。 / em>