当我们在 django 中添加数据库字段时,我们通常会编写models.CharField(max_length=100, null=True, blank=True)
。使用ForeignKey
, DecimalField
等也是如此。拥有的基本区别是什么
null=True
仅限null=True
blank=True
仅限blank=True
null=True
, blank=True
关于不同的( CharField
, ForeignKey
, ManyToManyField
, DateTimeField
)字段。使用 1/2/3 有哪些优点 / 缺点?
null=True
在数据库中的列上设置NULL
(与NOT NULL
)。 Django 字段类型(如DateTimeField
或ForeignKey
空值将在 DB 中存储为NULL
。
blank=True
确定表单中是否需要该字段。这包括管理员和您自己的自定义表单。如果blank=True
则不需要该字段,而如果该字段为False
,则该字段不能为空。
两者的组合是如此频繁,因为通常如果您要允许表单中的字段为空,那么您还需要您的数据库允许该字段的NULL
值。 CharField
和TextField
是一个例外,它在 Django 中永远不会保存为NULL
。空值作为空字符串( ''
)存储在 DB 中。
几个例子:
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
可能有一个用例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
Django 永远不会将CHAR
和TEXT
类型保存为NULL
,因此不需要null=True
。但是,您可以手动将其中一个字段设置为 “ None
以强制将其设置为NULL
。如果您有可能需要的场景,则仍应包含null=True
。
这就是 ORM 如何为 Django 1.8 映射blank
和null
字段
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)
为PostgreSQL 9.4创建的数据库字段是:
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)
)
为MySQL 5.6创建的数据库字段是:
CREATE TABLE Test (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`charNull` VARCHAR(10) NULL DEFAULT NULL,
`charBlank` VARCHAR(10) NOT NULL,
`charNullBlank` VARCHAR(10) NULL DEFAULT NULL,
`intNull` INT(11) NULL DEFAULT NULL,
`intBlank` INT(11) NOT NULL,
`intNullBlank` INT(11) NULL DEFAULT NULL,
`dateNull` DATETIME NULL DEFAULT NULL,
`dateBlank` DATETIME NOT NULL,
`dateNullBlank` DATETIME NULL DEFAULT NULL
)
如 Django Model Field 中所述: 链接
以下参数可用于所有字段类型。所有都是可选的。
null
Field.null
如果为True
,Django 将在数据库中将空值存储为NULL
。默认值为False
。
避免在基于字符串的字段(如CharField
和TextField
上使用null
,因为空字符串值将始终存储为空字符串,而不是NULL
。如果基于字符串的字段具有null=True
,则表示它具有 “无数据” 的两个可能值: NULL
和空字符串。在大多数情况下,为 “无数据” 提供两个可能的值是多余的; Django 约定是使用空字符串,而不是NULL
。
对于基于字符串和非基于字符串的字段,如果要在表单中允许空值,则还需要设置blank=True
,因为null
参数仅影响数据库存储(请参阅blank
)。
注意
使用 Oracle 数据库后端时,无论此属性如何,都将存储值 NULL 以表示空字符串
blank
Field.blank
如果为True
,则允许该字段为空。默认值为False
。
请注意,这与null
不同。 null
纯粹与数据库相关,而blank
与验证相关。如果字段为blank=True
,则表单验证将允许输入空值。如果字段为blank=False
,则将需要该字段。