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

622

Когда мы добавляем поле базы данных в django, мы обычно пишем models.CharField(max_length=100, null=True, blank=True). То же самое делается с ForeignKey, DecimalField и т.д. Какова основная разница в том, что

  • null=True только
  • blank=True только
  • null=True, blank=True

относительно разных (CharField, ForeignKey, ManyToManyField, DateTimeField) полей. Каковы преимущества/недостатки использования 1/2/3?

  • 6
    У вас есть хорошие ответы по этому поводу здесь: stackoverflow.com/questions/8159310/… а здесь: stackoverflow.com/questions/4384098/…
  • 2
    Хорошего чтения: b-list.org/weblog/2006/jun/28/…
Показать ещё 1 комментарий
Теги:
django-models

9 ответов

785
Лучший ответ

null=True устанавливает NULL (по сравнению с NOT NULL) в столбце в вашей БД. Пустые значения для типов полей Django, такие как DateTimeField или ForeignKey, будут сохранены как NULL в БД.

blank=True определяет, потребуется ли поле в формах. Сюда входят администратор и собственные пользовательские формы. Если blank=True, тогда поле не потребуется, тогда как если оно False, поле не может быть пустым.

Комбинация этих двух команд настолько частая, что, как правило, если вы хотите, чтобы поле было пустым в вашей форме, вам также понадобится ваша база данных, чтобы разрешить значения NULL для этого поля. Исключением является CharField и TextField s, которые в 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.

  • 0
    В своем объяснении models.DateTimeField (blank = True) вы говорите, что если этот DateTimeField оставить пустым, возникает ошибка IntegrityError. Но я подумал, что blank = True означает, что поле не должно быть заполнено пользователем, так почему же IntegrityError?
  • 7
    IntegrityError возникает, когда Django пытается сохранить запись в базе данных. Поле не обязательно должно быть заполнено пользователем, и это проблема, потому что на уровне базы данных оно не равно нулю.
Показать ещё 8 комментариев
72

Таким образом 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
)
  • 32
    Другими словами, blank не влияет на базу данных, и null контролирует, допускает ли столбец базы данных значения NULL . Этот ответ - очень длинный способ сказать это, и не предоставляет никакой полезной информации о blank .
  • 17
    @CarlMeyer: я хотел посмотреть, как он будет отображаться в базе данных и обмениваться, так как это сэкономит время для других, чтобы сделать то же самое. Теория против примера имеет значение, когда дело доходит до ассимиляции и фиксации памяти. На самом деле, я не стал добавлять отображение для базы данных, которую я не использовал. Спасибо за отрицание. Количество людей, которые нашли это полезным, очевидно, не согласны с вами.
Показать ещё 2 комментария
17

Как указано в описании поля 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, поле будет необходимо.

15

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

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

blank=True/False, относящийся к проверке формы

6

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

Когда дело доходит до 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

Вот пример поля с пустым = true и null = true   description = models.TextField(blank = True, null = True)

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

и

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

0
null = True

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

blank = True

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

0

Я думаю, вам может быть интересно сохранить пустой, nullable CharField как null, а не как пустую строку. Об этом много обсуждений, и очень практичная проблема, с которой вы можете столкнуться (например, вы хотите добавить URL-адрес openid для каждого пользователя, который может быть нулевым и должен быть уникальным).

0

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню