дифференцировать нуль = True, пусто = True в Django

904

Когда мы добавляем поле базы данных в 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?

user993563
источник
8
У вас есть хорошие ответы на этот вопрос здесь: stackoverflow.com/questions/8159310/… а здесь: stackoverflow.com/questions/4384098/…
juliomalegria
2
Хорошего чтения: b-list.org/weblog/2006/jun/28/…
Салман фон Аббас
Да, у меня также есть этот вариант использования ForeignKeyс blank=True, но без null=True. Когда модель сохранена, я хочу автоматически «опубликовать» ее, создав из нее опубликованную запись. Поэтому я не могу сохранить nullв базе данных, так как каждая модель должна быть «опубликована», но я хочу иметь возможность оставить поле пустым в admin.
OSA
Я думаю, что вас может заинтересовать [Сохранить пустой, обнуляемый CharField как ноль, а не как пустую строку] ( code.djangoproject.com/ticket/4136 ). Существует много дискуссий по этому поводу, и с очень практической проблемой вы можете столкнуться (например, вы хотите добавить URL-адрес openid для каждого пользователя, который может быть нулевым и должен быть уникальным).
ramwin

Ответы:

1084

null=Trueустанавливает NULL(против NOT NULL) на столбец в вашей БД. Пустые значения для типов полей Django, таких как DateTimeFieldили, ForeignKeyбудут сохранены как 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если вы хотите, чтобы поле всегда требовалось в формах, необязательно при работе с объектом через что-то вроде оболочки.)

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

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

CHARи TEXTтипы никогда не сохраняются как NULLв Django, так что в null=Trueэтом нет необходимости. Тем не менее, вы можете вручную установить одно из этих полей, Noneчтобы принудительно установить его как NULL. Если у вас есть сценарий, где это может быть необходимо, вы все равно должны включить null=True.

Крис Пратт
источник
8
IntegrityErrorвозникает, когда Django пытается сохранить запись в базе данных. Поле не обязательно должно быть заполнено пользователем, и это проблема, потому что на уровне базы данных оно не равно нулю.
Крис Пратт
5
Нет, Крис пытается указать, почему наличие пустого = True без нулевого = True может вызвать проблемы в DateTimeField.
Винод Куруп
4
ПРИМЕЧАНИЕ для пользователей Oracle: это неправда, что « CHARи TEXTНИКОГДА не сохраняются как NULLв Django». Это верно для большинства бэкэндов, но Oracle принудительно возвращает пустую строку в NULL, поэтому бэкэнд Django Oracle является исключением из вышеприведенного оператора Django Docs
stv
10
@ChrisPratt Незначительное исправление вашего поста: CharFields может быть сохранен как NULL в базе данных (перевод на NonePython), если вы установите null = True. В документах даже говорится, что следует избегать установки значения null = True, поскольку оно допускает два разных типа «пустых» значений. Я только что проверил это поведение с Django 1.8 / MySQL 5.6
Эдвард Д'Суза
3
Пока никто не собирается отметить сочетание: blank=True, null=False, default="something"?
Брайан Х.
125

Это как ORM карты blankи nullполя для Django 1.8

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
)
пользователь
источник
41
Другими словами, blankне влияет на базу данных и nullконтролирует, допускает ли столбец базы данных NULLзначения. Этот ответ - очень длинный способ сказать это, и не предоставляет никакой полезной информации о blank.
Карл Мейер
19
@CarlMeyer: я хотел посмотреть, как он будет отображаться в базе данных и обмениваться, так как это сэкономит время для других, чтобы сделать то же самое. Теория против примера имеет значение, когда дело доходит до ассимиляции и фиксации памяти. На самом деле, я старался добавить отображение для базы данных, которую я не использовал. Спасибо за отрицание. Количество людей, которые нашли это полезным, очевидно, не согласны с вами.
Пользователь
5
Это может быть полезным ответом, если вы сделаете некоторые краткие выводы из представленных данных, но я не думаю, что представление дампа необработанных данных является полезным ответом. В этом случае это на самом деле вводящий в заблуждение ответ, поскольку (без дальнейших комментариев) он подразумевает, что эффект обоих blankи nullдолжен отражаться в столбцах базы данных, когда фактически blankвлияет только на обработку Python, а не на столбцы базы данных. Другие могут высказать свое мнение, если сочтут это полезным; Люди, которые введены в заблуждение неправильным ответом, также могут подумать, что это было полезно.
Карл Мейер
4
Принятый ответ, которому почти 3 года, объясняет все подробно. Там нет смысла повторять ту же информацию здесь.
Пользователь
47

Как сказано в Django Model Field, ссылка: ссылка

Варианты поля

Следующие аргументы доступны для всех типов полей. Все необязательно.


null

Field.null

Если TrueDjango будет хранить пустые значения какNULL в базе данных. По умолчанию это False.

Избегайте использования nullстроковых полей, таких как CharFieldи TextFieldпотому, что пустые строковые значения всегда будут храниться как пустые строки, а не как NULL. Если у поля на основе строки есть null=True, это означает, что у него есть два возможных значения для «без данных»: NULLи пустая строка. В большинстве случаев избыточно иметь два возможных значения для «нет данных»; соглашение Джанго состоит в том, чтобы использовать пустую строку, а не NULL .

Как для строковых, так и для нестроковых полей вам также потребуется установить, blank=Trueесли вы хотите разрешить пустые значения в формах, так как nullпараметр влияет только на хранилище базы данных (см. blank).

Запись

При использовании базы данных Oracle, значение NULL будет сохранено для обозначения пустой строки независимо от этого атрибута.


blank

Field.blank

Если Trueполе может быть пустым. По умолчанию это False.

Обратите внимание, что это отличается от null. nullчисто связано с базой данных, тогда как blankсвязано с проверкой. Если поле имеет blank=True, проверка формы позволит ввести пустое значение. Если поле имеет blank=False, поле будет обязательным.

DiogoLR
источник
46

Важно понимать, что параметры в определении поля модели Django служат (как минимум) двум целям: определению таблиц базы данных и определению формата по умолчанию и проверке форм моделей. (Я говорю «по умолчанию», потому что значения всегда могут быть переопределены путем предоставления настраиваемой формы.) Некоторые параметры влияют на базу данных, некоторые параметры влияют на формы, а некоторые влияют на оба.

Что касается nullи blank, другие ответы уже дали понять, что первый влияет на определение таблицы базы данных, а второй влияет на проверку модели. Я думаю, что различие может быть сделано еще яснее, если рассмотреть варианты использования для всех четырех возможных конфигураций:

  • null=False, blank=False: Это конфигурация по умолчанию и означает, что значение требуется при любых обстоятельствах.

  • null=True, blank=True: Это означает, что поле является необязательным при любых обстоятельствах. (Как отмечается ниже, однако, это не рекомендуемый способ сделать поля на основе строк необязательными.)

  • null=False, blank=True: Это означает, что форма не требует значения, но база данных требует. Есть несколько вариантов использования для этого:

    • Чаще всего используется для необязательных полей на основе строк. Как отмечено в документации , идиома Django заключается в использовании пустой строки для указания отсутствующего значения. Если бы NULLтакже было разрешено, вы бы в конечном итоге двумя разными способами указать отсутствующее значение.

    • Другая распространенная ситуация - вы хотите автоматически рассчитывать одно поле на основе значения другого ( save()скажем, в вашем методе). Вы не хотите, чтобы пользователь предоставлял значение в форме (следовательно blank=True), но вы хотите, чтобы база данных обеспечивала постоянное предоставление значения ( null=False).

    • Другое использование, когда вы хотите указать, что ManyToManyFieldявляется необязательным. Поскольку это поле реализовано в виде отдельной таблицы, а не столбца базы данных, не nullимеет смысла . Значение по- blankпрежнему будет влиять на формы, однако, управляя тем, будет ли проверка успешной, если нет отношений.

  • null=True, blank=False: Это означает, что для формы требуется значение, а для базы данных - нет. Это может быть самая редко используемая конфигурация, но есть несколько вариантов ее использования:

    • Вполне разумно требовать, чтобы ваши пользователи всегда включали значение, даже если оно не требуется вашей бизнес-логикой. В конце концов, формы являются лишь одним из способов добавления и редактирования данных. Возможно, у вас есть код, который генерирует данные, которые не нуждаются в той же строгой проверке, которая требуется от редактора-человека.

    • Другой случай использования, который я видел, это когда у вас есть, ForeignKeyдля которого вы не хотите разрешать каскадное удаление . То есть при обычном использовании отношение всегда должно быть там ( blank=False), но если то, на что оно указывает, оказывается удаленным, вы не хотите, чтобы этот объект также был удален. В этом случае вы можете использовать null=Trueи on_delete=models.SET_NULLреализовать простой вид мягкого удаления .

Кевин Кристофер Генри
источник
1
Это идеальный ответ, все возможные комбинации объяснены очень кратко!
РусИ
1
Должен быть принятый ответ.
Том Мак
28

Возможно, у вас есть ответ, но до сегодняшнего дня трудно судить, следует ли указывать в поле значение null = True или пусто = True или оба. Лично я считаю, что предоставлять разработчикам так много вариантов - бесполезно и запутанно. Позвольте ручке нули или пробелы, как они хотят.

Я следую за этой таблицей из « Два совка Джанго» :введите описание изображения здесь

Таблица, показывающая, когда использовать пустое или пустое значение для каждого типа поля

saran3h
источник
26

Просто null=Trueопределяет, что база данных должна принимать NULLзначения, с другой стороны, blank=Trueопределяет при проверке формы, это поле должно принимать пустые значения или нет (Если blank=Trueона принимает форму без значения в этом поле и blank=False[значение по умолчанию] при проверке формы, она покажет Это поле обязательно для заполнения ошибка.

null=True/False связанный с базой данных

blank=True/False связанные с проверкой формы

Ранджу Р
источник
11

Вот пример поля с blank= True иnull=True

description = models.TextField (пусто = True, null = True)

В этом случае:: blank = Trueсообщает нашей форме, что можно оставить поле описания пустым

а также

null = True: сообщает нашей базе данных, что можно записать нулевое значение в поле db и не выдавать ошибку.

Stryker
источник
7
null = True

Означает, что для поля, подлежащего заполнению, нет ограничений базы данных, поэтому вы можете иметь объект с нулевым значением для заполненного поля, который имеет эту опцию.

blank = True

Значит, нет никаких ограничений валидации в формах Django. поэтому, когда вы заполняете modelFormэту модель, вы можете оставить поле с этой опцией незаполненным.

Милад Ходабандехлоо
источник
7

Вот основное отличие null=Trueи blank=True:

Значением по умолчанию обоих nullи blankявляется False. Оба эти значения работают на уровне поля, т.е. хотим ли мы сохранить поле nullили blank.

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
Соня Рани
источник
6

Значения по умолчанию null и blank являются False.

Null: это связано с базой данных. Определяет, будет ли данный столбец базы данных принимать нулевые значения или нет.

Пусто: это связано с проверкой. Он будет использоваться при проверке форм, при вызове form.is_valid ().

При этом совершенно нормально иметь поле с null = True и пустым = False. Значение на уровне базы данных может быть NULL, но на уровне приложения это обязательное поле.

Теперь, когда большинство разработчиков ошибаются: определение null = True для строковых полей, таких как CharField и TextField. Избегайте этого. В противном случае вы получите два возможных значения «без данных», а именно: « Нет» и пустую строку. Наличие двух возможных значений «нет данных» является избыточным. Соглашение Django - использовать пустую строку, а не NULL.

sharif_42
источник
5

Когда мы сохраняем что-либо в админке Django, происходит двухэтапная проверка, на уровне Django и на уровне базы данных. Мы не можем сохранить текст в числовом поле.

База данных имеет тип данных NULL, это ничего. Когда Django создает столбцы в базе данных, он указывает, что они не могут быть пустыми. И если вы попытаетесь сохранить NULL, вы получите ошибку базы данных.

Также на уровне Django-Admin все поля являются обязательными по умолчанию, вы не можете сохранить пустое поле, Django выдаст вам ошибку.

Итак, если вы хотите сохранить пустое поле, вам нужно разрешить его на уровне Django и базы данных. blank = True - разрешит пустое поле в админ-панели. null = True - позволит сохранить NULL в столбце базы данных.

Юрий Коц
источник
5

Там есть одна точка, где null=True было бы необходимо, даже для CharFieldили, TextFieldи это когда в базе данных установлен uniqueфлаг для столбца.

Другими словами, если у вас есть уникальный Char / TextField в Django, вам нужно использовать это:

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

Для неуникальных CharField или TextField вам лучше не пропускать, null=Trueиначе некоторые поля будут установлены как NULL, а другие как "", и вам придется каждый раз проверять значение поля для NULL.

Нитин Нэйн
источник
3

null - для базы данных, а пустое - для проверки полей, которые вы хотите отобразить в пользовательском интерфейсе, например в текстовом поле, чтобы получить фамилию человека. Если lastname = models.charfield (blank = true), он не просил пользователя ввести фамилию, поскольку это необязательное поле. Если lastname = models.charfield (null = true), то это означает, что если это поле не получает никакого значения от пользователя, оно будет храниться в базе данных в виде пустой строки "".

Tabish
источник
1

Значение 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 = 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'})
        }

Тогда поле 'name' не будет обязательным (из-за пробела = True в модели), а поле 'address' будет обязательным (из-за пробела = 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'}),
    )

Тогда оба поля («имя» и «адрес») будут обязательными, «поскольку поля, определенные декларативно, остаются как есть» ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) т. е. по умолчанию для атрибута 'required' поля формы установлено значение True, и для этого потребуется заполнить поля 'name' и 'address', даже если в модели для поля установлено значение blank = True.

Карлос Рибейро
источник
0

null - по умолчанию False, если True, Django будет хранить пустой как ноль в базе данных.

пусто - по умолчанию False, если true, это поле может быть пустым

больше, перейдите на https://docs.djangoproject.com/en/3.0/topics/db/models/

Vansh Bhardwaj
источник
0

Эта таблица ниже демонстрирует основные различия:

+--------------------------------------------------------------------+
| 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           |
+--------------------------------------------------------------------+
lavee_singh
источник
0

Очень простыми словами ,

Пробел отличается от нуля.

нуль является чисто базой данных , связанными , в то время как заготовка проверки связанной (обязательно в форме) .

Если null=TrueДжанго будет store empty values as NULL in the database. Если поле имеет blank=True, проверка формы будет allow entry of an empty value. Если поле имеет пустое значение = False, поле будет обязательным.

Яши
источник