Django的Model可以设置字段的null属性和blank属性。
null属性是针对数据库而言的,null=True将设置数据库的COLUMN为NULL(或者NOT NULL),而blank为True将不会影响数据库的结构,依然是必填。但是在Django里面,是可选的。即Form不会是required,Django自带的admin页面不要求必填了。
具体作用到数据库,是这样:
1 2 3 4 5 6 7 8 9 10 11 12 |
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 的结果如下 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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 的结果如下 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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 ) |
可以看出,数据库的字段是否可以为空完全取决于null属性,和blank没有关系。
那么为什么需要需要两个变量分开呢? 想象这样一种场景:我们需要用户的forms必填某一个选项,但是是否存储到数据库,就取决于其他的一些情况了。再如,我们需要用户必须输入,但是我们用其他方式(除了Django之外,例如用shell维护数据库的时候)时,可以不用设置这些字段,这时候就可以设置null=True,blak=False。
另外要注意的是,有些字段是不适合设置null或blank的,参考下表:
Field 类型 | 设置null=True | 设置blank=True |
---|---|---|
CharField, TextField, SlugField, EmailField, CommaSeparatedIntegerField等 |
不要设置 django规定储存空字符串来代表空值, 当从数据库中读取NULL或空值时都为空字符串 |
可以设置 设置后允许接受widget中为空值(即不填写), 储存到数据库时空值变为空字符串 |
FileField, ImageField |
不要设置 django实际储存的是路径的字符串, 因此同上 |
可以设置 同上 |
BooleanField | 不要设置 因为有NullBooleanField代替 |
不要设置 |
IntegerField, FloatField, DecimalField等 |
可以设置 如果你希望在数据库中能储存NULL |
可以设置 设置后允许接受widget中为空值(即不填写), 设置为True时必须同时设置null=True |
DateTimeField, DateField, TimeField等 |
可以设置 如果你希望在数据库中能储存NULL |
可以设置 设置后允许接受widget中为空值(即不填写), 设置为True时必须同时设置null=True |
ForeignKey, ManyToManyField, OneToOneField |
可以设置 如果你希望在数据库中能储存NULL |
可以设置 设置后允许接受widget中为空值(即不填写) |
GenericIPAddressField | 可以设置 如果你希望在数据库中能储存NULL |
可以设置 设置后允许接受widget中为空值(即不填写) |
IPAddressField | 不推荐设置 用GenericIPAddressField代替 |
不推荐设置 用GenericIPAddressField代替 |