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

use*_*563 819 python django django-models

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

  1. null=True 只要
  2. blank=True 只要
  3. null=True, blank=True

在相对于不同的(CharField,ForeignKey,ManyToManyField,DateTimeField)字段.使用1/2/3有哪些优点/缺点?

Chr*_*att 990

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

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

两者的组合是如此频繁,因为通常如果您要在表单中允许字段为空,那么您还需要您的数据库来允许NULL该字段的值.例外是CharFields和TextFields,它们在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
Run Code Online (Sandbox Code Playgroud)

显然,这两个选项在使用时没有逻辑意义(但是,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
Run Code Online (Sandbox Code Playgroud)

CHAR并且TEXT类型永远不会NULL被Django 保存,因此null=True是不必要的.但是,您可以手动将其中一个字段设置None为强制将其设置为NULL.如果您有可能需要的场景,您仍应该包括null=True.

  • 当Django尝试将记录保存到数据库时,会引发`IntegrityError`.该字段不需要由用户填写,这就是问题,因为在数据库级别它不是null. (8认同)
  • @ChrisPratt对你的帖子进行小修正:如果设置null = True,CharFields*可以*在数据库中保存为NULL(在Python中转换为"None").[docs](https://docs.djangoproject.com/en/1.9/ref/models/fields/#null)甚至说要避免设置null = True,因为它允许两种不同的"空白"值.我刚用Django 1.8/MySQL 5.6测试了这种行为 (7认同)
  • 不,Chris正在试图指出为什么如果没有null = True会使blank = True会导致DateTimeField出现问题. (5认同)
  • 对Oracle用户的注意:Django"`CHAR`和`TEXT`永远不会被保存为"NULL".对于大多数后端都是如此,但Oracle会强制将空字符串设置为NULL,因此Django Oracle后端是上述语句的一个例外[Django Docs](https://docs.djangoproject.com/en/1.9/ref/车型/场/#django.db.models.Field.null) (4认同)
  • 我认为user798719指的是blank的值,在你的例子中它应该是False而不是True:models.DateTimeField(blank = False)#raises IntegrityError if blank (2认同)
  • 没有人会提及“ blank = True”,“ null = False”,“ default =“ something”`的组合吗? (2认同)

use*_*ser 107

这就是Django 1.8 的ORM映射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)        
Run Code Online (Sandbox Code Playgroud)

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)
)
Run Code Online (Sandbox Code Playgroud)

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
)
Run Code Online (Sandbox Code Playgroud)

  • 换句话说,`blank`对数据库没有影响,`null`控制数据库列是否允许'NULL`值.这个答案是一个很长的说法,并没有提供有关`blank`的任何有用信息. (37认同)
  • @CarlMeyer:我想看看它如何映射到数据库并共享,因为它可以节省其他人做同样的事情的时间.理论与实例在同化和承诺记忆方面有所不同.事实上,我开始为我没有使用的数据库添加映射.谢谢你的downvote.发现这种有用的人数明显不同意你的意见. (17认同)
  • 如果您从所提供的数据中得出一些总结性结论,这可能是一个有用的答案,但我不认为提供原始数据转储是一个有用的答案.在这种情况下,它实际上是一个误导性的答案,因为(没有进一步的评论)它暗示'blank`和`null`的效果应该反映在数据库列中,而实际上`blank`只影响Python处理,而不是数据库列.如果其他人发现它有用,他们可以自由地投票; 那些被误导性回答误导的人也有可能_think_它很有用. (4认同)
  • 接受的答案将近3年,详细解释了所有内容.这里重复相同的信息毫无意义. (4认同)

小智 41

如Django Model Field中所述:链接

现场选择

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


null

Field.null

如果True,Django将NULL在数据库中存储空值.默认是False.

避免null在基于字符串的字段上使用,例如CharField,TextField因为空字符串值将始终存储为空字符串,而不是NULL.如果基于字符串的字段具有null=True,则表示它具有"无数据"的两个可能值:NULL和空字符串.在大多数情况下,为"无数据"提供两个可能的值是多余的; Django约定是使用空字符串,而不是NULL.

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

注意

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


blank

Field.blank

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

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


Kev*_*nry 32

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

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

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

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

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

    • 此配置的最常见用途是可选的基于字符串的字段.如文档中所述,Django习惯用法是使用空字符串来表示缺失值.如果NULL也允许,最终会有两种不同的方式来表示缺失值.

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

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

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

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

    • 我见过的另一个用例就是当你有一个ForeignKey你不希望允许级联删除时.也就是说,在正常使用中,关系应该总是在那里(blank=False),但是如果它指向的东西碰巧被删除了,你也不希望删除这个对象.在这种情况下,您可以使用null=Trueon_delete=models.SET_NULL实现一种简单的软删除.

  • 这是一个完美的答案,所有可能的组合都以非常简洁的方式解释! (4认同)

Ran*_*u R 24

简单地null=True定义数据库应该接受NULL值,另一方面blank=True定义表单验证这个字段是否应该接受空白值(如果blank=True它接受该字段中没有值的表单和blank=False表单验证时的[默认值]它将显示此字段是必需的错误.

null=True/False 与数据库有关

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


sar*_*n3h 15

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

我按照这个表格: 在此输入图像描述

在此输入图像描述

  • 仅供参考,自 Django 3.1 起,“NullBooleanField”已被弃用,转而使用“BooleanField(null=True)”:https://docs.djangoproject.com/en/3.1/ref/models/fields/#nullbooleanfield (4认同)
  • 嘿@ArdiNusawan,它来自《 Django的两个独家新闻》一书。https://www.goodreads.com/book/show/25447991-two-scoops-of-django (2认同)

Str*_*ker 11

这是带有blank= True和的字段的示例null=True

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

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

null = True:告诉我们的数据库可以在db字段中记录一个空值并且不给出错误。


小智 9

null 和 blank 的默认值为 False。

Null:与数据库相关。定义给定的数据库列是否接受空值。

空白:与验证相关。它将在表单验证期间使用,当调用 form.is_valid() 时。

话虽如此,拥有一个 null=True 和 blank=False 的字段是完全没问题的。这意味着在数据库级别该字段可以为 NULL,但在应用程序级别它是必填字段。

现在,大多数开发人员都弄错了:为基于字符串的字段(例如 CharField 和 TextField)定义 null=True。避免这样做。否则,您最终将有两个可能的“无数据”值,即:和空字符串。“无数据”有两个可能的值是多余的。Django 约定是使用空字符串,而不是 NULL。


ram*_*win 6

我认为您可能对 将空的可为空的CharField保存为null而不是空字符串感兴趣。关于此的讨论很多,您可能会遇到一个非常实际的问题(例如,您想为每个用户添加一个openid URL,该URL可以为null,并且应该是唯一的)。


Mil*_* Kh 6

null = True
Run Code Online (Sandbox Code Playgroud)

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

blank = True
Run Code Online (Sandbox Code Playgroud)

意味着没有django形式的验证约束。因此,当您modelForm为此模型填写时,可以不填写此选项。


小智 6

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

两者的默认值nullblank值为False。这两个值都在字段级别起作用,即我们是否要保留字段nullblank

null=True将字段的值设置为NULL即无数据。它基本上是针对数据库列的值。

date = models.DateTimeField(null=True)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


小智 6

null = True || blank = True || null = True && blank = True

class TestModel(models.Model):
    field1 = models.CharField(max_length=100, null=True)
    field2 = models.CharField(max_length=100, blank=True)   # it's not a correct way
    field3 = models.CharField(max_length=100, null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

数据库字段用于:MySQL

CREATE TABLE TestModel (
     `id`        INT(10)        NOT     NULL      AUTO_INCREMENT,

     `field1`    VARCHAR(100)   NULL    DEFAULT   NULL,
     `field2`    VARCHAR(100)   NOT     NULL,
     `field3`    VARCHAR(100)   NULL    DEFAULT   NULL,
)
Run Code Online (Sandbox Code Playgroud)

案例01:null = True

db:   db   field is accepts null value
form: form field is `required`

NB: DB IS ACCEPTS NULL VALUE, BUT FORM FIELD IS REQUIRED. SO FORM IS 
SUBMITTED WHEN THIS FIELD HAVE SOME VALUE. it's good.
Run Code Online (Sandbox Code Playgroud)

案例02:blank = True

db:   db   field is not accepts null value
form: form field is `optional`

NB: FORM IS VALID WITHOUT ANY VALUE, BUT DB IS NOT ACCEPTS NULL VALUE.
SO THE FORM IS SUBMITTED WITHOUT ANY VALUE THEN BOOM. it's worst.
Run Code Online (Sandbox Code Playgroud)

案例03:null = True && blank = True

db:   db   field is accepts null value
form: form field is `optional`

NB: HERE FORM FIELD IS OPTIONAL & FORM IS VALID WITHOUT ANY VALUE 
& DB ALSO ACCEPTS NULL VALUE. SO, IT'S BEST TO USE `null=True && blank=True`
Run Code Online (Sandbox Code Playgroud)

:)


Yur*_*ots 5

当我们在Django admin中保存任何内容时,将在Django级别和数据库级别进行两步验证。我们无法在数字字段中保存文本。

数据库的数据类型为NULL,没什么。当Django在数据库中创建列时,它指定它们不能为空。而且,如果您尝试保存NULL,则会出现数据库错误。

同样在Django-Admin级别,默认情况下所有字段都是必填字段,您无法保存空白字段,Django会抛出错误。

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


Nit*_*ain 5

有一点null=True甚至在CharFieldor 上也有必要TextField,那就是数据库unique为该列设置了标志。

换句话说,如果您在Django中具有唯一的Char / TextField,则需要使用以下代码:

models.CharField(blank=True, null=True, unique=True)
Run Code Online (Sandbox Code Playgroud)

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

  • 令人惊讶的是,唯一正确解释为什么 NULL 如此重要的答案。 (2认同)