14

В чем разница между null=True и blank=True в Django?

11

Проблема с использованием параметров null и blank в моделях Django

Когда мы добавляем поле модели в 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)? Хочу понять преимущества и недостатки выбора каждого из этих вариантов.

Буду признателен за разъяснения и примеры использования, которые помогут прояснить эту тему!

5 ответ(ов)

16

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

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

Комбинация этих двух параметров встречается часто, потому что, как правило, если вы собираетесь разрешить полю быть пустым в вашей форме, вам также нужно, чтобы ваша база данных позволяла значения NULL для этого поля. Исключением являются CharField и TextField, которые в Django никогда не сохраняются как NULL. Пустые значения хранятся в базе данных как пустая строка ('').

Несколько примеров:

models.DateTimeField(blank=True) # вызывает IntegrityError, если пустое

models.DateTimeField(null=True) # NULL разрешен, но должен быть заполнен в форме

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

models.CharField(blank=True) # Все в порядке, пустое хранится как ''

models.CharField(null=True) # NULL разрешен, но никогда не будет установлен как NULL

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

1

В Django 1.8 ORM обрабатывает поля blank и null следующим образом:

Для класса модели Test, определённого как:

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
)

Обратите внимание, что:

  • Поле с null=True может хранить значение NULL в базе данных.
  • Поле с blank=True не требует заполнения при валидации форм Django, что делает его не обязательным к заполнению на уровне приложения.
  • В PostgreSQL поля, где задан только blank=True, по умолчанию будут созданы как NOT NULL.
  • В MySQL также будут установлены аналогичные ограничения.
0

В Django null=True и blank=True имеют разные назначения и используются в разных контекстах.

  1. null=True определяет, что поле в базе данных может принимать значение NULL. Это означает, что при сохранении записи в базе данных, это поле может быть пустым (не заданным).

  2. blank=True связано с валидацией форм. Если blank=True, это означает, что поле может быть оставлено пустым при отправке формы. В случае если blank=False (значение по умолчанию), при валидации формы будет выдана ошибка This field is required, если поле не было заполнено.

Итак, можно выделить ключевые различия:

  • null=True/False относится к базе данных.
  • blank=True/False относится к валидации форм.

Обратите внимание, что для поля, которое может быть NULL в базе данных и пустым в форме, необходимо устанавливать оба атрибута: null=True и blank=True.

0

Пример поля с параметрами blank=True и null=True в Django:

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

В данном случае:

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

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

0

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

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

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

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь