Django: Ошибка NULL в поле модели, несмотря на значение по умолчанию
Мой класс модели определен следующим образом: [django 5.0]
class Vendor(models.Model):
"""
ORM representing vendors
Relationships:
A vendor may have many documents
"""
id = models.AutoField(
primary_key=True,
)
name = models.CharField(
max_length=255,
blank=True,
db_default='',
default='',
)
logo_uri = models.CharField(
max_length=255,
blank=True,
db_default='',
default='',
)
web_url = models.CharField(
max_length=255,
blank=True,
db_default='',
default=None,
)
created_on = models.DateTimeField(
auto_now_add=True,
null=False,
)
def __str__(self) -> str:
return f"{self.name}"
class Meta:
ordering = ["created_on"]
verbose_name = "vendor"
verbose_name_plural = "vendors"
Я использую MySQL и проверил DDL базы данных - значение по умолчанию для указанных столбцов установлено как ''. Если я вставляю с помощью SQL-оператора непосредственно в MySQL, все работает нормально, и значения по умолчанию присваиваются соответствующим образом -
INSERT INTO `core_vendor`
(`name`,
`created_on`)
VALUES
('TES',
NOW()
);
Однако когда я пытаюсь программно вставить через django -
vendor = Vendor()
vendor.name='TES2'
vendor.save()
Я получаю ошибку
django.db.utils.IntegrityError: (1048, "Column 'web_url' cannot be null")
Хотя web_url
имеет значение по умолчанию, назначенное на уровне django и DB. Есть мысли, где я ошибаюсь?
<1>> используется db_default
в случае, если значение отсутствует, но здесь вы задали default=None
. Таким образом, db_default
- это то, что Django сгенерирует как SQL при построении таблицы. Таким образом, он напишет что-то вроде
CREATE TABLE vendor (
-- …
web_url varchar(255) DEFAULT ''
)
но затем, из-за default=None
, он сделает запрос:
INSERT INTO vendor (web_url)
VALUES (NULL);
поскольку вы передаете значение в явном виде, это приводит к ошибкам.
Это также объясняется в документации по db_default=…
[Django-doc]:
Если установлены оба значения
db_default
иField.default
, тоdefault
будет иметь приоритет при создании экземпляров в коде Python.db_default
по-прежнему будет устанавливаться на уровне базы данных и использоваться при вставке строк вне ORM или при добавлении нового поля в миграции.