在django中区分null = True,blank = True
当我们在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
空值将在数据库中存储为NULL
。
blank=True
决定了表单中是否需要该字段。 这包括管理员和您自己的自定义表单。 如果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
的用例,但是通过某些东西来处理一个对象时可选像壳一样)。
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
。
这是ORM如何映射blank
和null
字段的Django 1.8
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
,则该字段将是必需的。