Django: NULL error on model field despite default value
My model class is defined as follows: [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"
I am using MySQL and have checked the database DDL - the default value for specified columns is set as ''. If I insert using a SQL statement directly in MySQL it works fine and default values are assigned as appropriate -
INSERT INTO `core_vendor`
(`name`,
`created_on`)
VALUES
('TES',
NOW()
);
However when I programatically try to insert via django -
vendor = Vendor()
vendor.name='TES2'
vendor.save()
I receive an error
django.db.utils.IntegrityError: (1048, "Column 'web_url' cannot be null")
Though web_url has a default value assigned at django and DB level. Any thoughts on where I am incorrect?
The db_default is used on case the value is missing, but here you have set the default=None. db_default is thus what Django will generate as SQL when constructing the table. It will thus write something like
CREATE TABLE vendor (
-- …
web_url varchar(255) DEFAULT ''
)
but then, because of the default=None, it will make a query:
INSERT INTO vendor (web_url)
VALUES (NULL);
since you pass a value explicitly, it thus errors.
This is also explained in the documentation on db_default=… [Django-doc]:
If both
db_defaultandField.defaultare set,defaultwill take precedence when creating instances in Python code.db_defaultwill still be set at the database level and will be used when inserting rows outside of the ORM or when adding a new field in a migration.