diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 9345bc0fe0b..1524ad2fcd7 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -465,8 +465,9 @@ How Django knows to UPDATE vs. INSERT You may have noticed Django database objects use the same ``save()`` method for creating and changing objects. Django abstracts the need to use ``INSERT`` -or ``UPDATE`` SQL statements. Specifically, when you call ``save()``, Django -follows this algorithm: +or ``UPDATE`` SQL statements. Specifically, when you call ``save()`` and the +object's primary key attribute does **not** define a +:attr:`~django.db.models.Field.default`, Django follows this algorithm: * If the object's primary key attribute is set to a value that evaluates to ``True`` (i.e., a value other than ``None`` or the empty string), Django @@ -475,6 +476,11 @@ follows this algorithm: didn't update anything (e.g. if primary key is set to a value that doesn't exist in the database), Django executes an ``INSERT``. +If the object's primary key attribute defines a +:attr:`~django.db.models.Field.default` then Django executes an ``UPDATE`` if +it is an existing model instance and primary key is set to a value that exists +in the database. Otherwise, Django executes an ``INSERT``. + The one gotcha here is that you should be careful not to specify a primary-key value explicitly when saving new objects, if you cannot guarantee the primary-key value is unused. For more on this nuance, see `Explicitly specifying @@ -490,6 +496,12 @@ which returns ``NULL``. In such cases it is possible to revert to the old algorithm by setting the :attr:`~django.db.models.Options.select_on_save` option to ``True``. +.. versionchanged:: 3.0 + + ``Model.save()`` no longer attempts to find a row when saving a new + ``Model`` instance and a default value for the primary key is provided, and + always executes an ``INSERT``. + .. _ref-models-force-insert: Forcing an INSERT or UPDATE diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt index 435755f732a..f133c58654b 100644 --- a/docs/releases/3.0.txt +++ b/docs/releases/3.0.txt @@ -372,6 +372,27 @@ Tests Backwards incompatible changes in 3.0 ===================================== +``Model.save()`` when providing a default for the primary key +------------------------------------------------------------- + +:meth:`.Model.save` no longer attempts to find a row when saving a new +``Model`` instance and a default value for the primary key is provided, and +always performs a single ``INSERT`` query. In older Django versions, +``Model.save()`` performed either an ``INSERT`` or an ``UPDATE`` based on +whether or not the row exists. + +This makes calling ``Model.save()`` while providing a default primary key value +equivalent to passing :ref:`force_insert=True ` to +model's ``save()``. Attempts to use a new ``Model`` instance to update an +existing row will result in an ``IntegrityError``. + +In order to update an existing model for a specific primary key value, use the +:meth:`~django.db.models.query.QuerySet.update_or_create` method or +``QuerySet.filter(pk=…).update(…)`` instead. For example:: + + >>> MyModel.objects.update_or_create(pk=existing_pk, defaults={'name': 'new name'}) + >>> MyModel.objects.filter(pk=existing_pk).update(name='new name') + Database backend API --------------------