Fixed #29129 -- Skipped UPDATE when adding a model instance with inherited primary key that has a default.

This commit is contained in:
Abhijeet Viswa 2020-02-26 23:19:05 +05:30 committed by Mariusz Felisiak
parent 7e15795bf0
commit babd412685
3 changed files with 14 additions and 4 deletions

View File

@ -855,8 +855,8 @@ class Model(metaclass=ModelBase):
not raw and not raw and
not force_insert and not force_insert and
self._state.adding and self._state.adding and
self._meta.pk.default and meta.pk.default and
self._meta.pk.default is not NOT_PROVIDED meta.pk.default is not NOT_PROVIDED
): ):
force_insert = True force_insert = True
# If possible, try an UPDATE. If that doesn't update anything, do an INSERT. # If possible, try an UPDATE. If that doesn't update anything, do an INSERT.

View File

@ -46,3 +46,7 @@ class SelfRef(models.Model):
class PrimaryKeyWithDefault(models.Model): class PrimaryKeyWithDefault(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4) uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
class ChildPrimaryKeyWithDefault(PrimaryKeyWithDefault):
pass

View File

@ -12,8 +12,8 @@ from django.test import (
from django.utils.translation import gettext_lazy from django.utils.translation import gettext_lazy
from .models import ( from .models import (
Article, ArticleSelectOnSave, FeaturedArticle, PrimaryKeyWithDefault, Article, ArticleSelectOnSave, ChildPrimaryKeyWithDefault, FeaturedArticle,
SelfRef, PrimaryKeyWithDefault, SelfRef,
) )
@ -139,6 +139,12 @@ class ModelInstanceCreationTests(TestCase):
with self.assertNumQueries(1): with self.assertNumQueries(1):
PrimaryKeyWithDefault().save() PrimaryKeyWithDefault().save()
def test_save_parent_primary_with_default(self):
# An UPDATE attempt is skipped when an inherited primary key has
# default.
with self.assertNumQueries(2):
ChildPrimaryKeyWithDefault().save()
class ModelTest(TestCase): class ModelTest(TestCase):
def test_objects_attribute_is_only_available_on_the_class_itself(self): def test_objects_attribute_is_only_available_on_the_class_itself(self):