首页 文章

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

提问于
浏览
674

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

  • null=True

  • blank=True

  • null=Trueblank=True

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

12 回答

  • 4

    有一点,即使在 CharFieldTextField 上也需要 null=True ,这就是数据库为列设置 unique 标志的时候 .

    换句话说,如果你在Django中有一个独特的Char / TextField,你需要使用它:

    models.CharField(blank=True, null=True, unique=True)
    

    对于非唯一的CharField或TextField,最好不要跳过 null=True 否则某些字段将设置为NULL而其他字段将设置为“”,并且您必须每次都检查字段值为NULL .

  • 1

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

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

    两者的组合是如此频繁,因为通常如果您还需要数据库允许该字段的 NULL 值 . 例外是 CharFieldTextField s,它们在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 的用例,但是当通过像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 .

  • 16
    null = True
    

    意味着对于要填充的字段没有数据库约束,因此对于具有此选项的填充,您可以拥有一个具有空值的对象 .

    blank = True
    

    意味着在django形式中没有验证约束 . 因此,当您为此模型填写 modelForm 时,您可以保留此选项未填充的字段 .

  • 2

    这里是 null=Trueblank=True 的主要区别:

    nullblank 的默认值均为False . 这两个值都适用于字段级别,即我们是否要保留字段 nullblank .

    null=True 将字段的值设置为 NULL ,即没有数据 . 它基本上用于数据库列值 .

    date = models.DateTimeField(null=True)
    

    blank=True 确定表单中是否需要该字段 . 这包括管理员和您自己的自定义表单 .

    title = models.CharField(blank=True) // title can be kept blank. 将在数据库 ("") 中存储 . null=True blank=True 这意味着该字段在所有情况下都是可选的 .

    epic = models.ForeignKey(null=True, blank=True)
    // The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values a
    
  • 10

    只需 null=True 定义数据库应接受 NULL 值,另一方面 blank=True 定义表单验证此字段是否应接受空白值(如果 blank=True 它接受该字段中没有值的表单,并且 blank=False [默认值]表单验证它将显示 This field is required 错误 .

    null=True/False 与数据库有关

    blank=True/False 与表单验证有关

  • 1

    我想你可能对Save empty, nullable CharField's as null rather than as an empty string感兴趣 . 关于这个问题有很多讨论,并且你可能会遇到一个非常实际的问题(例如,你想为每个用户添加一个openid url,它可以为null并且应该是唯一的) .

  • 23

    当我们在Django管理员中保存任何内容时,会在Django级别和数据库级别上执行两步验证 . 我们无法在数字字段中保存文本 .

    数据库的数据类型为NULL,没什么 . 当Django在数据库中创建列时,它指定它们不能为空 . 如果您尝试保存NULL,您将收到数据库错误 .

    同样在Django-Admin级别,默认情况下所有字段都是必需的,你不能保存空白字段,Django会给你一个错误 .

    因此,如果要保存空白字段,则需要在Django和数据库级别上允许它 . blank = True - 将允许管理面板中的空字段null = True - 将允许将NULL保存到数据库列 .

  • 1

    在查看Django模型定义中的选项时,了解它们(至少)有两个目的是至关重要的:定义数据库表,定义模型表单的默认格式和验证 . (我说“默认”是因为可以通过提供自定义表单来覆盖值 . )某些选项会影响数据库,某些选项会影响表单,而某些选项会影响两者 .

    当谈到 nullblank 时,其他答案已经明确表明前者影响数据库表定义和后者影响模型验证 . 我认为通过查看所有四种可能配置的用例,可以更清楚地区分:

    • null=Falseblank=False :这是默认配置,表示在所有情况下都需要该值 .

    • null=Trueblank=True :这意味着该字段在所有情况下都是可选的 . (如下所述,这不是建议使基于字符串的字段可选的方法 . )

    • null=Falseblank=True :这意味着表单不需要值,但数据库需要 . 这有很多用例:

    • 此配置的最常见用途是可选的基于字符串的字段 . 作为noted in the documentation,Django成语是使用空字符串来表示缺失值 . 如果还允许使用 NULL ,则最终会有两种不同的方式来指示缺失值 .

    • 另一种常见情况是,您希望根据另一个字段的值自动计算一个字段(例如,在您的 save() 方法中) . 您不希望用户在表单中提供值(因此 blank=True ),但您确实希望数据库强制始终提供值( null=False ) .

    • 此配置的另一个用途是当您想要指示 ManyToManyField 是可选的时 . 因为此字段是作为单独的表而不是数据库列实现的,所以null is meaningless . 但是, blank 的值仍将影响表单,控制在没有关系时验证是否成功 .

    • null=Trueblank=False :这意味着表单需要一个值,但数据库不需要 . 这可能是最不经常使用的配置,但有一些用例:

    • 要求您的用户始终包含值是完全合理的,即使您的业务逻辑实际上并不需要它 . 毕竟,表单只是添加和编辑数据的一种方式 . 您可能拥有生成数据的代码,这些数据不需要您需要人工编辑器的相同严格验证 .

    • 我见过的另一个用例就是当你有 ForeignKey 时,你不希望允许cascade deletion . 也就是说,在正常使用中,关系应始终存在( blank=False ),但如果它指向的东西恰好被删除,则您也不希望删除此对象 . 在这种情况下,您可以使用 null=Trueon_delete=models.SET_NULL 来实现一种简单的soft deletion .

  • 804

    你可以得到你的答案直到今天很难判断是否将null = True或blank = True或两者都放入一个字段 . 我个人认为向开发人员提供这么多选项是非常无用和困惑的 . 让他们想要处理空值或空白 .

    我按照这个表格:

  • 1

    以下是 blank= Truenull=True 的字段示例

    description = models.TextField(blank = True,null = True)

    在这种情况下: blank = True :告诉我们的表单可以将描述字段留空

    null = True :告诉我们的数据库可以在db字段中记录空值而不会出错 .

  • 80

    如Django Model Field中所述:Link

    字段选项

    以下参数可用于所有字段类型 . 一切都是可选的 .

    null

    Field.null

    如果 True ,Django会将空值存储为数据库中的 NULL . 默认值为 False .

    避免在基于字符串的字段(如 CharFieldTextField )上使用 null ,因为空字符串值将始终存储为空字符串,而不是 NULL . 如果基于字符串的字段具有 null=True ,则表示它有"no data"的两个可能值: NULL ,以及空字符串 . 在大多数情况下,"no data"有两个可能的值是多余的; Django约定是使用空字符串,而不是 NULL .

    对于基于字符串和非基于字符串的字段,如果您希望在表单中允许空值,则还需要设置 blank=True ,因为 null 参数仅影响数据库存储(请参阅 blank ) .

    注意使用Oracle数据库后端时,无论此属性如何,都将存储值NULL以表示空字符串

    空白

    Field.blank

    如果 True ,则允许该字段为空 . 默认值为 False .

    请注意,这与 null 不同 . null 纯粹与数据库相关,而 blank 与验证相关 . 如果字段具有 blank=True ,则表单验证将允许输入空值 . 如果字段具有 blank=False ,则将需要该字段 .

  • 2

    这就是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
    )
    

相关问题