在django中添加数据库字段时,通常会这样写:
models.CharField(max_length=100, null=True, blank=True)
ForeignKey
,DecimalField
等也是如此。 仅
null=True
仅
blank=True
null=True
,blank=True
针对不同的(
CharField
,ForeignKey
,ManyToManyField
,DateTimeField
)字段。使用1/2/3的优点/缺点是什么?#1 楼
null=True
在数据库的列上设置NULL
(与NOT NULL
相对)。 Django字段类型(例如DateTimeField
或ForeignKey
)的空白值将作为NULL
存储在数据库中。blank
确定是否需要表单中的字段。这包括管理员和您的自定义表单。如果为blank=True
,则不需要该字段,而如果为False
,则该字段不能为空白。两者的组合非常常见,因为通常情况下,如果您要允许将字段保留为空白在您的表单中,您还将需要数据库来允许该字段的
NULL
值。 CharField
和TextField
例外,它们在Django中从未保存为NULL
。空值以空字符串(''
)的形式存储在数据库中。几个示例:
models.DateTimeField(blank=True) # raises IntegrityError if blank
models.DateTimeField(null=True) # NULL allowed, but must be filled out in a form
显然,这两个选项没有使用没有逻辑上的意义(尽管如果希望始终以表单形式要求字段,则
null=True, blank=False
可能有一个用例,通过诸如shell之类的对象处理时是可选的。)models.CharField(blank=True) # No problem, blank is stored as ''
models.CharField(null=True) # NULL allowed, but will never be set as NULL
CHAR
和TEXT
类型永远不会被Django保存为NULL
,因此null=True
是不必要的。但是,您可以将以下字段之一手动设置为None
,以将其强制设置为NULL
。如果您有可能需要这样做的情况,则仍应包括null=True
。评论
当Django尝试将记录保存到数据库时,引发IntegrityError。用户不需要填写该字段,这就是问题所在,因为在数据库级别它不是null。
–克里斯·普拉特(Chris Pratt)
2013年6月25日14:32
否,克里斯(Chris)试图指出为什么在没有null = True的情况下使用blank = True会导致DateTimeField中出现问题。
– Vinod Kurup
13年8月15日在14:58
给Oracle用户的提示:“ Django绝不将CHAR和TEXT保存为NULL”是不正确的。对于大多数后端来说都是如此,但是Oracle会将一个空字符串强制为NULL,因此Django Oracle后端是上述Django Docs语句的一个例外。
–stv
16年5月20日在15:02
@ChrisPratt对您的帖子进行较小的更正:如果将null设置为True,CharFields可以在数据库中保存为NULL(在Python中转换为None)。文档甚至说避免设置null = True,因为它允许两种不同的“空白”值。我刚刚使用Django 1.8 / MySQL 5.6测试了此行为
–爱德华·德·索萨(Edward D'Souza)
16年8月3日,17:14
没有人会提及以下组合:空白=真,空=假,默认=“某物”?
– Brian H.
17年5月3日,12:25
#2 楼
这就是ORM如何映射Django 1.8的blank
和null
字段的方法。为PostgreSQL 9.4创建的数据库字段是:
class Test(models.Model):
charNull = models.CharField(max_length=10, null=True)
charBlank = models.CharField(max_length=10, blank=True)
charNullBlank = models.CharField(max_length=10, null=True, blank=True)
intNull = models.IntegerField(null=True)
intBlank = models.IntegerField(blank=True)
intNullBlank = models.IntegerField(null=True, blank=True)
dateNull = models.DateTimeField(null=True)
dateBlank = models.DateTimeField(blank=True)
dateNullBlank = models.DateTimeField(null=True, blank=True)
为MySQL 5.6创建的数据库字段是:
CREATE TABLE Test (
id serial NOT NULL,
"charNull" character varying(10),
"charBlank" character varying(10) NOT NULL,
"charNullBlank" character varying(10),
"intNull" integer,
"intBlank" integer NOT NULL,
"intNullBlank" integer,
"dateNull" timestamp with time zone,
"dateBlank" timestamp with time zone NOT NULL,
"dateNullBlank" timestamp with time zone,
CONSTRAINT Test_pkey PRIMARY KEY (id)
)
评论
换句话说,空白对数据库没有影响,而null控制数据库列是否允许NULL值。这个答案说起来确实很长,并且没有提供任何有关空白的有用信息。
–卡尔·迈耶
2014年9月4日于20:01
@CarlMeyer:我想看看它如何映射到数据库并共享,因为这样可以节省其他人的时间。在吸收和致力于记忆方面,理论与范例会有所不同。实际上,我不愿意为未使用的数据库添加映射。谢谢你的反对。觉得有用的人的数量显然与您不同意。
–用户
2014年9月5日4:49
如果您从呈现的数据中得出一些总结性结论,这可能是一个有用的答案,但是我认为呈现原始数据转储不是一个有用的答案。在这种情况下,这实际上是一个误导性的答案,因为(无需进一步评论)它意味着应在数据库列中反映空白和null的影响,而实际上空白仅影响Python处理,而不影响数据库列。如果其他人觉得有用,则可以自由投票;对于被误导性答案误导的人,也有可能认为它很有用。
–卡尔·迈耶
2014年9月6日下午14:26
已经接受了将近3年的答案详细解释了所有内容。在这里重复相同的信息没有意义。
–用户
2014年9月6日14:53
#3 楼
理解Django模型字段定义中的选项至少有两个作用是至关重要的:定义数据库表,定义默认格式和验证模型形式。 (我说“默认”是因为可以始终通过提供自定义表单来覆盖这些值。)某些选项会影响数据库,某些选项会影响表单,而某些选项会同时影响两者。null
,其他答案已经明确表明,前者影响数据库表定义,而后者影响模型验证。我认为,通过查看所有四种可能的配置的用例,可以使区分更加清楚:blank
,null=False
:这是默认配置,意味着在所有情况下都需要该值blank=False
,null=True
:这意味着该字段在所有情况下都是可选的。 (但是,如下所述,这不是建议使基于字符串的字段为可选的方法。)blank=True
和null=False
:这意味着表单不需要值,但是数据库却不需要。有许多用例:最常见的用法是用于可选的基于字符串的字段。如文档中所述,Django习惯用法是使用空字符串表示缺少的值。如果还允许使用
blank=True
,则最终会用两种不同的方法来指示缺失值。另一种常见情况是,您想根据另一个字段的值自动计算一个字段(例如,使用
NULL
方法)。您不希望用户以某种形式提供值(因此save()
),但是您希望数据库强制始终提供值(blank=True
)。另一个用途是当您要指示
null=False
是可选的时。因为此字段是作为单独的表而不是数据库列实现的,所以ManyToManyField
毫无意义。但是,null
的值仍会影响表单,控制在没有关系时验证是否成功。blank
,null=True
:这意味着表单需要一个值,但数据库没有。这可能是最不常用的配置,但是有一些用例:要求用户始终包含一个值是完全合理的,即使您实际上并不需要它也是如此商业逻辑。毕竟,表单只是添加和编辑数据的一种方式。您可能拥有的代码生成的数据不需要与人工编辑器一样严格的验证。希望允许级联删除。也就是说,在正常使用中,该关系应该始终存在(
blank=False
),但是如果它指向的对象恰好被删除,则您也不想删除该对象。在这种情况下,您可以使用ForeignKey
和blank=False
来实现一种简单的软删除。评论
这是一个完美的答案,所有可能的组合都以非常简洁的方式进行了说明!
– RusI
3月23日16:19
#4 楼
如Django模型字段参考中所述:链接字段选项
以下参数可用于所有字段类型。所有都是可选的。
null
Field.null
如果True
,Django将在数据库中将空值存储为NULL
。默认值为False
。避免在基于字符串的字段(例如
null
和CharField
)上使用TextField
,因为空字符串值将始终存储为empty 字符串,而不是
NULL
。如果基于字符串的字段具有null=True
,则该表示它具有“无数据”的两个可能值:
NULL
和空的字符串。在大多数情况下,为
“无数据”设置两个可能的值是多余的; Django约定是使用空字符串,而不是
NULL
。对于基于字符串的字段和基于非字符串的字段,您还需要
设置
blank=True
您希望允许使用形式为空的值,因为null
参数仅影响数据库存储(请参阅blank
)。注意
在Oracle数据库后端,无论此属性如何,都将存储NULL值来表示空字符串。
blank
Field.blank
如果True
,该字段允许为空白。默认值为False
。请注意,这与
null
不同。 null
完全与数据库相关,而blank
与验证相关。如果字段具有
blank=True
,则表单验证将允许输入空值。如果字段具有
blank=False
,则将需要该字段。#5 楼
您可能有答案,但是直到今天,仍然很难判断是否将null = True或blank = True或两者都放在一个字段中。我个人认为为开发人员提供这么多的选择是非常无用的和令人困惑的。让处理空值或空值成为他们想要的。我遵循这张表,来自Django的两个独家新闻:
#6 楼
简单地null=True
定义数据库应该接受NULL
值,另一方面blank=True
定义在表单验证中该字段应该接受还是不接受空白值(如果blank=True
接受该字段中没有值的表单,并且blank=False
[默认值]在表单验证中将显示字段为必填错误。与数据库有关的
null=True/False
与表单验证有关的
blank=True/False
#7 楼
这是带有blank= True
和null=True
的字段的示例说明= models.TextField(blank = True,null = True)
在这种情况下:
blank = True
:告诉我们的形式,可以将描述字段保留为空白和
null = True
:告诉我们的数据库可以在db字段中记录一个空值,并且没有给出错误。#8 楼
如果设置null=True
,它将允许将数据库列的值设置为NULL
。如果仅设置blank=True
,则django会将列的默认新值设置为""
。有一点,即使在null=True
或CharField
上也需要TextField
,这就是数据库为unique
设置了标记列。在这种情况下,您将需要使用以下代码:a_unique_string = models.CharField(blank=True, null=True, unique=True)
对于非唯一的
null=True
或CharField
,最好跳过TextField
。否则,某些字段将被设置为NULL
,而另一些字段将被设置为""
,并且您每次都必须检查NULL
的字段值。#9 楼
null = True
意味着要填充的字段没有数据库的约束,因此可以为该对象提供一个具有空值的对象。
blank = True
意味着django形式的验证没有约束。因此,当您为此模型填写一个
modelForm
时,可以保留该选项未填写的字段。#10 楼
这是null=True
和blank=True
的主要区别:null
和blank
的默认值均为False。这两个值都在字段级别起作用,即我们是否要保留字段null
或blank
。它基本上是用于数据库列的值。null=True
确定是否需要表格中的字段。这包括管理员和您自己的自定义表单。NULL
blank=True
将存储在数据库中。title = models.CharField(blank=True) // title can be kept blank.
("")
这意味着该字段在所有情况下都是可选的。 /> date = models.DateTimeField(null=True)
#11 楼
null和blank的默认值为False。Null:与数据库相关。定义给定的数据库列是否将接受空值。
空白:与验证相关。在调用form.is_valid()时,将在表单验证期间使用它。
话虽如此,具有null = True和blank = False的字段是完全可以的。在数据库级别上,该字段可以为NULL,但在应用程序级别上,该字段为必填字段。
现在,大多数开发人员都将其弄错了:为基于字符串的字段定义null = True,例如CharField和TextField。避免这样做。否则,您最终将有两个可能的“无数据”值,即:无和空字符串。为“无数据”设置两个可能的值是多余的。 Django约定是使用空字符串,而不是NULL。
#12 楼
当我们在Django admin中保存任何内容时,将在Django级别和数据库级别进行两步验证。我们无法在数字字段中保存文本。数据库的数据类型为NULL,没什么。当Django在数据库中创建列时,它指定它们不能为空。而且,如果您尝试保存NULL,则会出现数据库错误。
在Django-Admin级别上,默认情况下所有字段都是必填字段,您无法保存空白字段,Django会抛出一个错误。
因此,如果要保存空白字段,则需要在Django和数据库级别上允许它。
blank = True-将在管理面板中允许空字段
为空= True-将允许将NULL保存到数据库列。
#13 楼
null是用于数据库,空白是用于字段验证,您想要在用户界面(例如,文本字段)上显示该字段以获取人员的姓氏。如果lastname = models.charfield(blank = true),则不要求用户输入姓氏名称,因为这是现在的可选字段。
#14 楼
下表说明了主要区别:+--------------------------------------------------------------------+
| Purpose | null=True | blank = True |
|--------------------------|------------------|----------------------|
| Field can be empty in DB | Do this | Unaffected |
|--------------------------|------------------|----------------------|
| ModelForm(required field)| Unaffected | field not required |
|--------------------------|------------------|----------------------|
| Form Validation | Unaffected | field not required |
|--------------------------|------------------|----------------------|
| on_delete=SET_NULL | Need this | Unaffected |
+--------------------------------------------------------------------+
#15 楼
用非常简单的话来说,空白不同于null。
null纯粹与数据库有关,而空白与验证有关(以表格形式要求)。
如果为
null=True
,则Django将为store empty values as NULL in the database
。如果字段具有blank=True
,则表单验证将为allow entry of an empty value
。如果字段的空白为False,则必须填写该字段。#16 楼
模型中null = True和blank = True的含义还取决于在表单类中如何定义这些字段。假设您定义了以下类:
class Client (models.Model):
name = models.CharField (max_length=100, blank=True)
address = models.CharField (max_length=100, blank=False)
如果表单类的定义如下:
class ClientForm (ModelForm):
class Meta:
model = Client
fields = ['name', 'address']
widgets = {
'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})
}
然后,“名称”字段将不是必填项(由于模型中的blank = True),而“地址”字段将是必填项(由于模型)。但是,如果ClientForm类的定义是这样的:
class ClientForm (ModelForm):
class Meta:
model = Client
fields = ['name', 'address']
name = forms.CharField (
widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
)
address = forms.CharField (
widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
)
然后,两个字段(“名称”和“地址”)为必填项,“因为声明性定义的字段保持原样”(https://docs.djangoproject.com/zh-CN/3.0/topics/forms/modelforms/),即“必需”属性的默认值表单字段的“ True”为True,即使在模型中将该字段设置为blank = True,这也需要填写字段“名称”和“地址”。
#17 楼
Null纯粹与数据库有关,而空白则与验证有关。如果字段具有blank = True,则在Django管理站点上的验证将允许输入空值。如果字段空白为False,则该字段为必填#18 楼
null-默认为False,如果为True,则Django将在数据库中将空存储为null。
空白-默认为False
,如果为true,则该字段允许为空白
更多,转到
https://docs.djangoproject.com/en/3.0/topics/db/models/
#19 楼
设置null=true
时,如果未填写该字段,它将在数据库中设置null
。如果设置了
blank='true
,则不会对该字段设置任何值。
评论
您在这里有关于此的很好的答案:stackoverflow.com/questions/8159310/…和这里:stackoverflow.com/questions/4384098/…好的阅读:b-list.org/weblog/2006/jun/28/…
是的,我也有这个用例,外键为blank = True,但没有null = True。保存模型后,我想通过在其中创建已发布的条目来自动“发布”它。所以我不能将null保存到数据库,因为每个模型都必须“发布”,但是我希望能够在admin中将该字段留空。
我认为您可能对[将空的可为空的CharField保存为null而不是空字符串](code.djangoproject.com/ticket/4136)感兴趣。关于此的讨论很多,您可能会遇到一个非常实际的问题(例如,您想为每个用户添加一个openid URL,该URL可以为null,并且应该是唯一的)。