Home > OS >  DateField Django default does not apply to database:
DateField Django default does not apply to database:

Time:07-01

When doing the basic models on my django app, I have encountered this issue:

The model for a Product stands like this in my app:

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()

But the catalog_inclusion_date isn't working as intended. After migrating the models to the MySQL database and attempting to insert an entry on the table with this SQL sentence:

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')

I get the following output:

ERROR 1364 (HY000): Field 'catalog_inclusion_date' doesn't have a default value

Thanks in advance.

Edit: In MySQL, after doing DESCRIBE cap_table;, I get the following output:

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`)
) 

CodePudding user response:

You confused blank and null as explained in the documentation. Your field should have been:

catalog_inclusion_date = models.DateTimeField(null=True)

That way you could have inserted in MySQL and the column would have contained a null field.

Some Django instructions are only validation-related as is the case for blank=True in models, while some are database-related, as is the case for null=True. Therefore, writing a model in Django and then SQL querying the database directly can yield surprising results in view of the "instructions" you wrote for the model. The Django ORM doesn't always translate all the python instructions into SQL code, but will enforce them on the application side. For instance, I just checked that the Django ORM (4.0.5) doesn't translate default='test' into SQL code for sqlite, despite that a default instruction exists.

In general, it is good practice to stay consistent and either keep the logic in the Django ORM, meaning that you should insert new objects using 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()

either to only use SQL (although much more cumbersome).

CodePudding user response:

There are two options:

catalog_inclusion_date = models.DateTimeField(blank=True, null=True)
Now the default value of the field is Null.

or

catalog_inclusion_date = models.DateTimeField(null=True, default=some_default_value) There your default is what you provide. default=datetime.now sets the default to the time of obj creation.

The code in your current form dictates to the database, that there should be a column but does not give a default value for this column.

  • Related