Fixed #29260 -- Skipped an UPDATE when adding a model instance with primary key that has a default.
This commit is contained in:
parent
e9f74f53cc
commit
85458e94e3
|
@ -15,6 +15,7 @@ from django.db import (
|
||||||
DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY, DatabaseError, connection,
|
DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY, DatabaseError, connection,
|
||||||
connections, router, transaction,
|
connections, router, transaction,
|
||||||
)
|
)
|
||||||
|
from django.db.models import NOT_PROVIDED
|
||||||
from django.db.models.constants import LOOKUP_SEP
|
from django.db.models.constants import LOOKUP_SEP
|
||||||
from django.db.models.constraints import CheckConstraint, UniqueConstraint
|
from django.db.models.constraints import CheckConstraint, UniqueConstraint
|
||||||
from django.db.models.deletion import CASCADE, Collector
|
from django.db.models.deletion import CASCADE, Collector
|
||||||
|
@ -842,6 +843,14 @@ class Model(metaclass=ModelBase):
|
||||||
if not pk_set and (force_update or update_fields):
|
if not pk_set and (force_update or update_fields):
|
||||||
raise ValueError("Cannot force an update in save() with no primary key.")
|
raise ValueError("Cannot force an update in save() with no primary key.")
|
||||||
updated = False
|
updated = False
|
||||||
|
# Skip an UPDATE when adding an instance and primary key has a default.
|
||||||
|
if (
|
||||||
|
not force_insert and
|
||||||
|
self._state.adding and
|
||||||
|
self._meta.pk.default and
|
||||||
|
self._meta.pk.default is not NOT_PROVIDED
|
||||||
|
):
|
||||||
|
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.
|
||||||
if pk_set and not force_insert:
|
if pk_set and not force_insert:
|
||||||
base_qs = cls._base_manager.using(using)
|
base_qs = cls._base_manager.using(using)
|
||||||
|
|
|
@ -3,6 +3,8 @@ Bare-bones model
|
||||||
|
|
||||||
This is a basic model with only two non-primary-key fields.
|
This is a basic model with only two non-primary-key fields.
|
||||||
"""
|
"""
|
||||||
|
import uuid
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,3 +42,7 @@ class SelfRef(models.Model):
|
||||||
# This method intentionally doesn't work for all cases - part
|
# This method intentionally doesn't work for all cases - part
|
||||||
# of the test for ticket #20278
|
# of the test for ticket #20278
|
||||||
return SelfRef.objects.get(selfref=self).pk
|
return SelfRef.objects.get(selfref=self).pk
|
||||||
|
|
||||||
|
|
||||||
|
class PrimaryKeyWithDefault(models.Model):
|
||||||
|
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
|
||||||
|
|
|
@ -10,7 +10,10 @@ from django.test import (
|
||||||
)
|
)
|
||||||
from django.utils.translation import gettext_lazy
|
from django.utils.translation import gettext_lazy
|
||||||
|
|
||||||
from .models import Article, ArticleSelectOnSave, FeaturedArticle, SelfRef
|
from .models import (
|
||||||
|
Article, ArticleSelectOnSave, FeaturedArticle, PrimaryKeyWithDefault,
|
||||||
|
SelfRef,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ModelInstanceCreationTests(TestCase):
|
class ModelInstanceCreationTests(TestCase):
|
||||||
|
@ -130,6 +133,11 @@ class ModelInstanceCreationTests(TestCase):
|
||||||
# ... but there will often be more efficient ways if that is all you need:
|
# ... but there will often be more efficient ways if that is all you need:
|
||||||
self.assertTrue(Article.objects.filter(id=a.id).exists())
|
self.assertTrue(Article.objects.filter(id=a.id).exists())
|
||||||
|
|
||||||
|
def test_save_primary_with_default(self):
|
||||||
|
# An UPDATE attempt is skipped when a primary key has default.
|
||||||
|
with self.assertNumQueries(1):
|
||||||
|
PrimaryKeyWithDefault().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):
|
||||||
|
|
Loading…
Reference in New Issue