在Django中null=True和空白=True有什么区别?

当我们在Django中添加模型字段时,我们通常会写:

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

ForeignKeyDecimalField等也是如此。它们之间的基本区别是什么:

  1. null=True而已
  2. blank=True而已
  3. null=Trueblank=True

对于不同的(CharFieldForeignKeyManyToManyFieldDateTimeField)字段?使用选项1、2或3的优点/缺点是什么?

450090 次浏览

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

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

两者的组合非常频繁,因为通常如果您要允许表单中的字段为空,您还需要您的数据库允许该字段为NULL值。例外是CharFields和TextFields,在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

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模型字段参考中所述:Link

字段选项

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


null

Field.null

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

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

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

说明

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


blank

Field.blank

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

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

简单地null=True定义数据库应接受NULL值,另一方面blank=True定义表单验证此字段应接受空白值或不接受(如果blank=True它接受该字段中没有值的表单,blank=False[默认值]表单验证它将显示此字段为必填项错误。

null=True/False与数据库相关

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

这是一个带有blank= Truenull=True的字段的示例

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

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

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

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

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

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

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

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

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

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

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

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

    • 最常见的用法是可选的基于字符串的字段。作为记在留档,Django的习惯用法是使用空字符串来指示缺失值。如果也允许NULL,您最终会有两种不同的方式来指示缺失值。(但是,如果字段也是unique,您必须使用null=True来防止多个空字符串无法通过唯一性检查。)

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

    • 另一种用法是当您想指示ManyToManyField是可选的时。因为此字段是作为单独的表而不是数据库列实现的,#1毫无意义blank的值仍然会影响表单,但是,控制在没有关系时验证是否会成功。

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

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

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

null = True

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

blank = True

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

这里是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=Trueblank=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

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

有一点即使在CharFieldTextField上也需要null=True,那就是当数据库为该列设置了#3标志时。在这种情况下,您需要使用以下命令:

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

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

您可能已经有了答案,但是直到今天,很难判断是将null=True还是blank=True或两者都放在一个字段中。我个人认为为开发人员提供这么多选项是非常无用和令人困惑的。让他们随意处理空值或空白。

我按照这个表,从两勺姜戈输入图片描述

显示每个字段类型何时使用null或空白的表

null和空白的默认值为False

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

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

也就是说,具有null=Trueblank=False的字段是完全可以的。这意味着在数据库级别,该字段可以是NULL,但在应用程序级别,它是必需的字段。

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

null用于数据库,空白用于字段验证,您希望在文本字段等用户交互界面上显示以获取人员的姓氏。如果lastname=models.charfield(空白=true),它没有要求用户输入姓氏,因为这是现在的可选字段。如果lastname=models.charfield(null=true),则意味着如果该字段没有从user获得任何值,则它将作为空字符串存储在数据库中 " ".

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

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

更多,继续https://docs.djangoproject.com/en/3.0/topics/db/models/

下表显示了主要差异:

+--------------------------------------------------------------------+| 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           |+--------------------------------------------------------------------+

用非常简单的话

空白不同于null。

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

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

模型中null=True和空白=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 = Clientfields = ['name', 'address']widgets = {'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})}

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

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

class ClientForm (ModelForm):class Meta:model = Clientfields = ['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”和“地址”)将是强制性的,"因为以声明方式定义的字段保持原样"https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/),即表单字段的“必需”属性的默认值为True,这将要求填写字段“name”和“地址”,即使在模型中,该字段已设置为空白=True。

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

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

Null纯粹与数据库相关,而空白与验证相关。如果字段具有空白=True,则在Django的管理站点上进行验证将允许输入空值。如果字段具有空白=False,则需要该字段

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.

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

参考:django nulldjango空白

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

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

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

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 wayfield3 = 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,)

case 01:null = True

db:   db   field is accepts null valueform: form field is `required`
NB: DB IS ACCEPTS NULL VALUE, BUT FORM FIELD IS REQUIRED. SO FORM ISSUBMITTED WHEN THIS FIELD HAVE SOME VALUE. it's good.

case-02:blank = True

db:   db   field is not accepts null valueform: 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 && blank = True

db:   db   field is accepts null valueform: 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`

:)

以下是它简单的回答:

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

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

Django模型中的每个选项都有两个目的

  1. 在数据库级别定义字段约束(例如SQL、PostgreSQL或任何其他)
  2. 在表单级别定义字段约束(在数据库层之上的框架级别)

现在让我们回到nullblank

  • blank与Django表单相关。它用于在admin或Django中验证Django表单。特别是当我们调用form.is_valid()
  • null与数据库相关。它告诉底层数据库该列是否允许保存null值。

例如,让我们看看下面的例子——

class Company(models.Model):name = models.CharField(max_length=100)website = models.UrlField()founded_on = models.DateField(blank=True, null=False)random_date = models.DateFeild(blank=False, null=True)random_text = models.TextField(null=True, blank=True)

我定义了一个Company模型,它有两个字段,我们在其中使用blanknull选项。让我们看看不同的字段会发生什么

  • founded_on:可以在表单级别(框架/语言级别)接收一个空的string值。当保存到数据库时,我们会提高IntegrityError,因为数据库不会接受null值,因为nullfalse

  • random_date:通过验证错误在表单级别(框架)接收空值,因为由于blank true在表单级别设置约束而不允许空白。但是,它也允许列在数据库层为null

  • random_text:这是一个选项,意味着该字段允许在数据库层保存为null,并且根据Django表单验证逻辑,由于blank=True,空的string值被允许为有效数据。简而言之,它可以接收空值(在框架级别,可以在数据库级别存储空值。

要解决所有这些混淆,请将您的数据库提交视为两层过程。

  • 首先,它填写表单,我们可以在其中调用框架级别的验证数据。
  • 其次,它有一个数据库级选项,有助于定义数据库约束。

这里blank是框架级别的东西,null是数据库级别的禁忌。

null=Trueblank=True是字段属性django.db.models.null与数据库相关,而空白与验证相关。

null

默认值为null=False。如果null=False,Django将不允许数据库列中的NULL值。

如果null=True,Django将在数据库列中将空值存储为NULL。对于CharField和TextField,django将使用空字符串"而不是NULL。避免对CharField和TextField使用null属性。一个例外是当CharField有unique=Trueblank=True时,则需要null=True

空白

默认值为blank=False。如果空白=False,则需要该字段。

如果blank=True,则该字段是可选的并且可以留空。空白=True与null=False将需要在模型上实现Clean()以编程方式设置任何缺失值。

根据留档,null确实与数据库相关。如果null=true,DB将空输入存储为null。否则,空字符串存储为空字符串。然而,如果空白=true,表单将验证它为ok,否则该字段将被表单视为“必需”。

两者默认都是false。