DateField Django по умолчанию не применяется к базе данных:
При создании базовых моделей в моем приложении django я столкнулся с такой проблемой:
В моем приложении модель для продукта выглядит следующим образом:
main_color = models.CharField(max_length=15)
secondary_color = models.CharField(max_length=15)
brand = models.CharField(max_length=30)
catalog_inclusion_date = models.DateTimeField(default=datetime.now, blank=True)
image_url = models.URLField(max_length=200)
description = models.TextField()
Но catalog_inclusion_date не работает так, как задумано. После переноса моделей в базу данных MySQL и попытки вставить запись в таблицу с таким SQL предложением:
INSERT INTO shoppingcart_cap(main_color, secondary_color, catalog_inclusion_date, brand, image_url, description, logo_color)
VALUES ('Red', 'Black', 'Adidas', 'https://www.rekordsport.es/uploads/photo/image/4920/gallery_A02506_1.JPG', 'Kid cap', 'White')
Я получаю следующий вывод:
ERROR 1364 (HY000): Field 'catalog_inclusion_date' doesn't have a default value
Заранее спасибо.
Edit: В MySQL, после выполнения DESCRIBE cap_table;
, я получаю следующий вывод:
CREATE TABLE `shoppingcart_cap` (
`id` bigint NOT NULL AUTO_INCREMENT,
`main_color` varchar(15) NOT NULL,
`secondary_color` varchar(15) NOT NULL,
`brand` varchar(30) NOT NULL,
`catalog_inclusion_date` date NOT NULL,
`image_url` varchar(200) NOT NULL,
`description` longtext NOT NULL,
`logo_color` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
)
Вы перепутали blank
и null
, как объясняется в документации. Ваше поле должно было быть:
catalog_inclusion_date = models.DateTimeField(null=True)
Таким образом, вы могли бы вставить в MySQL, и столбец содержал бы нулевое поле.
Некоторые инструкции Django связаны только с валидацией, как в случае с blank=True
в моделях, а некоторые связаны с базой данных, как в случае с null=True
. Поэтому написание модели в Django и последующий SQL-запрос к базе данных напрямую может дать неожиданные результаты с учетом "инструкций", которые вы написали для модели. Django ORM не всегда переводит все инструкции python в SQL-код, но обеспечивает их выполнение на стороне приложения. Например, я только что проверил, что Django ORM (4.0.5) не переводит default='test'
в SQL код для sqlite
, несмотря на то, что существует инструкция по умолчанию.
В целом, хорошая практика заключается в том, чтобы оставаться последовательным и либо сохранять логику в Django ORM, что означает, что вы должны вставлять новые объекты, используя python:
new_product = Product(
main_color='Red',
secondary_color='Black',
brand='Adidas',
catalog_inclusion_date=datetime.now(),
image_url='https://www.rekordsport.es/uploads/photo/image/4920/gallery_A02506_1.JPG',
description='Kid cap',
logo_color='White'
)
new_product.save()
либо использовать только SQL (хотя это гораздо более громоздко).
Есть два варианта:
catalog_inclusion_date = models.DateTimeField(blank=True, null=True)
Теперь значение поля по умолчанию - Null.
или
catalog_inclusion_date = models.DateTimeField(null=True, default=some_default_value)
Здесь ваше значение по умолчанию - это то, что вы предоставили. default=datetime.now
устанавливает значение по умолчанию на время создания obj.
Код в вашем текущем виде диктует базе данных, что должна быть колонка, но не дает значения по умолчанию для этой колонки.