ChatGPT解决这个技术问题 Extra ChatGPT

Django中null=True和blank=True有什么区别?

想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。

当我们在 django 中添加数据库字段时,我们通常会这样写:

models.CharField(max_length=100, null=True, blank=True)

ForeignKeyDecimalField 等也是如此。拥有的基本区别是什么

null=仅真 空白=仅真 null=真,空白=真

关于不同的(CharFieldForeignKeyManyToManyFieldDateTimeField)字段。使用 1/2/3 的优点/缺点是什么?

是的,我也有 ForeignKeyblank=True 的这个用例,但没有 null=True。保存模型后,我想通过创建已发布条目来自动“发布”它。所以我无法将 null 保存到数据库中,因为每个模型都必须“发布”,但我希望能够在管理员中将该字段留空。
我想您可能对 [将空的、可为空的 CharField 保存为 null 而不是空字符串](code.djangoproject.com/ticket/4136) 感兴趣。关于这个有很多讨论,你可能会遇到一个非常实际的问题(例如,你想为每个用户添加一个 openid url,它可以是 null 并且应该是唯一的)。
避免在基于字符串的字段(例如 CharField 和 TextField)上使用 null。 docs.djangoproject.com/en/3.1/ref/models/fields

e
eng.mrgh

null=True 在您的数据库中的列上设置 NULL(相对于 NOT NULL)。 DateTimeFieldForeignKey 等 Django 字段类型的空白值将作为 NULL 存储在数据库中。

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

两者的组合非常频繁,因为通常如果您要允许表单中的字段为空白,您还需要您的数据库允许该字段的 NULL 值。 CharFieldTextField 例外,它们在 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 的用例,在通过 shell 之类的东西处理对象时是可选的。)

models.CharField(blank=True) # No problem, blank is stored as ''

models.CharField(null=True) # NULL allowed, but will never be set as NULL

CHARTEXT 类型从不被 Django 保存为 NULL,因此 null=True 是不必要的。但是,您可以手动将这些字段之一设置为 None 以强制将其设置为 NULL。如果您有可能需要这样做的场景,您仍应包括 null=True


IntegrityError 在 Django 尝试将记录保存到数据库时引发。该字段不需要用户填写,这就是问题所在,因为在数据库级别它不为空。
我认为 user798719 指的是空白的值,在您的示例中应该是 False 而不是 True:models.DateTimeField(blank=False) # raises IntegrityError if blank
不,Chris 试图指出为什么在没有 null=True 的情况下使用 blank=True 会导致 DateTimeField 出现问题。
Oracle 用户注意:“CHARTEXT 永远不会被 Django 保存为 NULL”是不正确的。大多数后端都是如此,但 Oracle 会强制空字符串为 NULL,因此 Django Oracle 后端是上述语句 Django Docs 的一个例外
没有人会提到:blank=Truenull=Falsedefault="something" 的组合吗?
u
user

这就是 ORM 映射 blank & 的方式。 Django 1.8 的 null 字段

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
)

换句话说,blank 对数据库没有影响,而 null 控制数据库列是否允许 NULL 值。这个答案的说法很长,并且没有提供有关 blank 的任何有用信息。
@CarlMeyer:我想看看它如何映射到数据库并共享,因为它可以为其他人节省时间来做同样的事情。在同化和致力于记忆方面,理论与示例会有所不同。事实上,我特意为我不使用的数据库添加了映射。感谢您的反对。发现这很有用的人数显然不同意您的看法。
如果您从提供的数据中得出一些总结性结论,这可能是一个有用的答案,但我不认为提供原始数据转储是一个有用的答案。在这种情况下,它实际上是一个误导性的答案,因为(没有进一步评论)它暗示 blanknull 的效果应该反映在数据库列中,而实际上 blank 只影响 Python 处理,而不影响数据库列。其他人如果觉得有用,可以自由投票;对于被误导性答案误导的人来说,认为很有用也是可能的。
近 3 年的公认答案详细解释了一切。在这里重复相同的信息是没有意义的。
K
Kevin Christopher Henry

理解 Django 模型字段定义中的选项(至少)有两个目的是至关重要的:定义数据库表,以及定义模型表单的默认格式和验证。 (我说“默认”是因为这些值总是可以通过提供自定义表单来覆盖。)一些选项影响数据库,一些选项影响表单,还有一些影响两者。

说到nullblank,其他的答案已经很清楚了,前者影响数据库表定义,后者影响模型验证。我认为通过查看所有四种可能配置的用例可以使区别更加清晰:

null=False,blank=False:这是默认配置,意味着在所有情况下都需要该值。

null=True,blank=True:这意味着该字段在所有情况下都是可选的。但是,如下所述,这不是使基于字符串的字段可选的推荐方法。

null=False,blank=True:这意味着表单不需要值,但数据库需要。有许多用例: 最常见的用途是可选的基于字符串的字段。如文档中所述,Django 习惯用法是使用空字符串来指示缺失值。如果还允许 NULL,您最终将有两种不同的方式来指示缺失值。 (但是,如果该字段也是唯一的,则必须使用 null=True 以防止多个空字符串无法通过唯一性检查。)另一种常见情况是您希望根据另一个字段的值自动计算一个字段(在你的 save() 方法中,比如说)。您不希望用户在表单中提供值(因此空白=True),但您确实希望数据库强制始终提供值(null=False)。另一种用途是当您想要指示 ManyToManyField 是可选的时。因为该字段是作为单独的表而不是数据库列来实现的,所以 null 是没有意义的。但是,空白的值仍然会影响表单,控制在没有关系时验证是否成功。

最常见的用途是可选的基于字符串的字段。如文档中所述,Django 习惯用法是使用空字符串来指示缺失值。如果还允许 NULL,您最终将有两种不同的方式来指示缺失值。 (但是,如果该字段也是唯一的,则必须使用 null=True 来防止多个空字符串无法通过唯一性检查。)

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

另一种用途是当您想要指示 ManyToManyField 是可选的时。因为该字段是作为单独的表而不是数据库列来实现的,所以 null 是没有意义的。但是,空白的值仍然会影响表单,控制在没有关系时验证是否成功。

null=True,blank=False:这意味着表单需要一个值,但数据库不需要。这可能是最不常用的配置,但也有一些用例:要求用户始终包含一个值是完全合理的,即使您的业务逻辑实际上并不需要它。毕竟,表单只是添加和编辑数据的一种方式。您可能有生成数据的代码不需要人工编辑器所需的严格验证。我见过的另一个用例是当您有一个不希望允许级联删除的 ForeignKey 时。也就是说,在正常使用中,关系应该始终存在(空白=假),但如果它指向的东西恰好被删除,你不希望这个对象也被删除。在这种情况下,您可以使用 null=True 和 on_delete=models.SET_NULL 来实现一种简单的软删除。

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

我见过的另一个用例是当您有一个不希望允许级联删除的 ForeignKey 时。也就是说,在正常使用中,关系应该始终存在(空白=假),但如果它指向的东西恰好被删除,你不希望这个对象也被删除。在这种情况下,您可以使用 null=True 和 on_delete=models.SET_NULL 来实现一种简单的软删除。


这是一个完美的答案,所有可能的组合都以非常简洁的方式解释!
f
fedorqui

如 Django 模型字段参考中所述:Link

字段选项 以下参数适用于所有字段类型。所有都是可选的。 null Field.null 如果为 True,Django 会将空值作为 NULL 存储在数据库中。默认为假。避免在基于字符串的字段(例如 CharField 和 TextField)上使用 null,因为空字符串值将始终存储为空字符串,而不是 NULL。如果基于字符串的字段具有 null=True,这意味着它有两个可能的“无数据”值:NULL 和空字符串。在大多数情况下,“无数据”有两个可能的值是多余的。 Django 约定是使用空字符串,而不是 NULL。对于基于字符串和非基于字符串的字段,如果您希望在表单中允许空值,您还需要设置 blank=True,因为 null 参数仅影响数据库存储(请参阅空白)。注意 使用Oracle 数据库后端时,无论该属性如何,都会存储NULL 值来表示空字符串。默认为假。请注意,这与 null 不同。 null 纯粹与数据库相关,而空白与验证相关。如果一个字段有空白=真,表单验证将允许输入一个空值。如果某个字段的空白=False,则该字段将是必需的。


K
Kevin Christopher Henry

您可能会得到答案,但是直到今天还很难判断是否将 null=True 或 blank=True 或两者都放入字段。我个人认为给开发者提供这么多的选择是非常无用和混乱的。让他们随心所欲地处理空值或空白。

https://i.stack.imgur.com/TMMej.png

https://i.stack.imgur.com/gUanA.png


仅供参考,自 Django 3.1 起已弃用 NullBooleanField,而支持 BooleanField(null=True)docs.djangoproject.com/en/3.1/ref/models/fields/…
R
Ranju R

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

null=True/False 与数据库相关

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


S
Samsul Islam

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

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

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

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


N
Nitin Nain

如果设置 null=True,它将允许将数据库列的值设置为 NULL。如果您只设置 blank=True,django 会将列的默认新值设置为等于 ""

有一点即使在 CharFieldTextField 上也需要 null=True,即当数据库为列设置了 unique 标志时。在这种情况下,您需要使用它:

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

最好跳过 非唯一 CharFieldTextFieldnull=True。否则,某些字段将设置为 NULL 而其他字段将设置为 "" ,您必须每次检查 NULL 的字段值。


令人惊讶的是,唯一正确的答案为什么 NULL 很重要。
J
Javad Nikbakht

‍‍‍‍‍‍‍‍‍‍null和空白的默认值为False

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

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

话虽如此,拥有一个包含 null=Trueblank=False 的字段是完全可以的。意思是在数据库级别该字段可以是 NULL,但在应用程序级别它是一个必填字段。

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


M
Milad Khodabandehloo
null = True

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

blank = True

意味着在 django 表单中没有验证约束。因此,当您为此模型填写 modelForm 时,您可以将此选项留空。


S
Sonia Rani

以下是 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

i
iamdipta

空=真||空白=真||空 = 真 && 空白 = 真

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)

数据库字段: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,
)

案例01:空=真

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.

case-02:空白=真

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.

case-03: null = True && 空白 = 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`

:)


J
Javad Nikbakht

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

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

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

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


T
Tabish

null 用于数据库,空白用于您要在用户界面(如文本字段)上显示的字段验证,以获取人员的姓氏。如果 lastname=models.charfield (blank=true) 它不会要求用户输入姓氏,因为这是现在的可选字段。如果 lastname=models.charfield (null=true) 那么这意味着如果这个字段没有从用户那里得到任何值,那么它将作为一个空字符串“”存储在数据库中。


S
Shedrack

简单的答案是:Null 用于数据库表,而 Blank 用于 Django 表单。


V
Vivek

Null 纯粹与数据库相关,而空白与验证相关。如果一个字段有 blank=True ,Django 管理站点上的验证将允许输入一个空值。如果一个字段有 blank=False ,该字段将是必需的


S
Siva Sankar
Blank=False # this field is required.
Null=False # this field should not be null

Blank=True # this field is optional.
Null=True # Django uses empty string (''), not NULL.

注意:避免在基于字符串的字段(例如 CharFieldTextField 以及 FileField/ImageField)上使用 null=True

参考:Django nullDjango blank


K
Kapil Sharma

这是简单的答案:-

通过 null = True 我们告诉 数据库 模型的这个字段可以是 NULL,通过 blank = True 我们告诉 Django 模型的这个字段可以是 NULL


Y
Yash

用非常简单的话来说,

空白不同于空。

null 纯粹与数据库相关,而空白与验证相关(表单中需要)。

如果null=True,Django 将store empty values as NULL in the database。如果字段具有 blank=True,则表单验证将 allow entry of an empty value。如果某个字段的空白=False,则该字段将是必需的。


V
Vansh Bhardwaj

null - 如果为 True,则默认为 False,Django 将在数据库中将空存储为 null。

空白 - 如果允许该字段为空白,则默认为 False

更多,转到https://docs.djangoproject.com/en/3.0/topics/db/models/


l
lavee_singh

下表说明了主要区别:

+--------------------------------------------------------------------+
| Purpose                  | null=True        | blank = True         |
|--------------------------|------------------|----------------------|
| Field can be empty in DB | Do this          | Unaffected           |
|--------------------------|------------------|----------------------|
| ModelForm(required field)| Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| Form Validation          | Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| on_delete=SET_NULL       | Need this        | Unaffected           |
+--------------------------------------------------------------------+

C
Carlos Ribeiro

模型中 null=True 和 blank=True 的含义还取决于这些字段在表单类中是如何定义的。

假设您定义了以下类:

class Client (models.Model):
    name = models.CharField (max_length=100, blank=True)
    address = models.CharField (max_length=100, blank=False)

如果表单类是这样定义的:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']
        widgets = {
            'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
            'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})
        }

然后,“姓名”字段将不是强制性的(由于模型中的空白=True),“地址”字段将是强制性的(由于模型中的空白=False)。

但是,如果 ClientForm 类是这样定义的:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']

    name = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )
    address = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )

然后,两个字段('name' 和 'address')都将是强制性的,“因为以声明方式定义的字段保持原样”https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/),即“required”属性的默认值表单字段的值为 True,这将要求填写字段“名称”和“地址”,即使在模型中该字段已设置为空白 = True。


Y
Yilmaz

blank=True 可以设置为任何模型字段,以控制在表单中输入值时该字段是否可以留空。在这里,我们谈论的是输入数据。

null=True,如果我们为一个字段设置blank=True,则该模型字段不会接收任何值,那么当数据写入数据库时,数据库或 Django 必须对该字段做一些事情。对于任何类型的文本内容,数据库中都存储了一个空字符串,因此数据库中存储了一个值。对于日期字段或数字等其他类型的字段,我们使用特殊的数据类型“null”。如果字段可能没有值,则可以使用“null”,但默认情况下,Django 不允许使用“null”值。这就是您需要显式设置 null=True 的原因。

假设您为任何非文本字段设置了 blank=True,但您没有指定“null=True”,Django 将不知道要存储什么并且会抛出错误。


S
Saeed

当您设置 null=true 时,如果该字段未填写,它将在您的数据库中设置 null。如果您设置 blank=true,它将不会为该字段设置任何值。


B
Bello Victor

当您说 null=False 时,这意味着必须将数据传递到数据库才能保存。当您说空白=假时,这意味着必须从您的前端输入数据,反之亦然