协慌网

登录 贡献 社区

在 django 中区分 null = True,blank = True

当我们在 django 中添加数据库字段时,我们通常会编写models.CharField(max_length=100, null=True, blank=True) 。使用ForeignKeyDecimalField等也是如此。拥有的基本区别是什么

  1. null=True仅限null=True
  2. blank=True仅限blank=True
  3. null=Trueblank=True

关于不同的( CharFieldForeignKeyManyToManyFieldDateTimeField )字段。使用 1/2/3 有哪些优点 / 缺点?

答案

null=True在数据库中的列上设置NULL (与NOT NULL )。 Django 字段类型(如DateTimeFieldForeignKey空值将在 DB 中存储为NULL

blank=True确定表单中是否需要该字段。这包括管理员和您自己的自定义表单。如果blank=True则不需要该字段,而如果该字段为False ,则该字段不能为空。

两者的组合是如此频繁,因为通常如果您要允许表单中的字段为空,那么您还需要您的数据库允许该字段的NULL值。 CharFieldTextField是一个例外,它在 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 永远不会将CHARTEXT类型保存为NULL ,因此不需要null=True 。但是,您可以手动将其中一个字段设置为 “ None以强制将其设置为NULL 。如果您有可能需要的场景,则仍应包含null=True

这就是 ORM 如何为 Django 1.8 映射blanknull字段

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

避免在基于字符串的字段(如CharFieldTextField上使用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 ,则将需要该字段。