15👍
Consider this example. Suppose we have a simple model as
CONSTANT = 10
def foo_pk_default():
return CONSTANT
class Foo(models.Model):
id = models.IntegerField(primary_key=True, default=foo_pk_default)
name = models.CharField(max_length=10)
The main thing I have done in this example is, I did set a default callable function for Primary Keys. Also, I returned only a single value from the function, for the sake of demonstration.
## Django 2.2
In [5]: foo_instance_1 = Foo(name='foo_name_1')
In [6]: foo_instance_1.save()
In [7]: print(foo_instance_1.__dict__)
{'_state': , 'id': 10, 'name': 'foo_name_1'}
In [8]: foo_instance_2 = Foo(name='foo_name_2')
In [9]: foo_instance_2.save()
In [10]: print(foo_instance_2.__dict__)
{'_state': , 'id': 10, 'name': 'foo_name_2'}
## Django 3.X
In [6]: foo_instance_1 = Foo(name='foo_name_1')
In [7]: foo_instance_1.save()
In [8]: print(foo_instance_1.__dict__)
{'_state': , 'id': 10, 'name': 'foo_name_1'}
In [9]: foo_instance_2 = Foo(name='foo_name_2')
In [10]: foo_instance_2.save()
# Raised "IntegrityError: UNIQUE constraint failed: music_foo.id"
Conclusion
In Django<3.0
, the Model.save()
will do an update or insert operation if there is a PK value associated with the model instance whereas in Django>=3.0
, only perform an insert operation hence the UNIQUE constraint failed
exception.
Impact of this change in the current project
Since this Django change is only applicable when a new instance is created and we usually don’t set any default value functions for Primary Keys.
In short, this change will not make any problem unless you are providing default value during model instance creation.
0👍
It should be read carefully
no longer attempts to find a row when saving a new Model instance
and a default value for the primary key is provided,
So in case you are going to create new object with id that is already in database it would now fail instead of having behavior similar to update_or_create as it will now preform INSERT
statement instead of UPDATE
- TypeError: create_superuser() missing 1 required positional argument: 'profile_picture'
- How to make migrations for a reusable Django app?
- How do I select from multiple tables in one query with Django?