diff --git a/django/db/models/base.py b/django/db/models/base.py index 180df0cff2..58bf74dc91 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1118,7 +1118,7 @@ class Model(AltersData, metaclass=ModelBase): and not force_insert and not force_update and self._state.adding - and (meta.pk.has_default() or meta.pk.has_db_default()) + and all(f.has_default() or f.has_db_default() for f in meta.pk_fields) ): force_insert = True # If possible, try an UPDATE. If that doesn't update anything, do an INSERT. diff --git a/tests/composite_pk/models/tenant.py b/tests/composite_pk/models/tenant.py index 810fb50db7..9817b40fac 100644 --- a/tests/composite_pk/models/tenant.py +++ b/tests/composite_pk/models/tenant.py @@ -1,3 +1,5 @@ +import uuid + from django.db import models @@ -46,8 +48,8 @@ class Comment(models.Model): class Post(models.Model): pk = models.CompositePrimaryKey("tenant_id", "id") - tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE) - id = models.UUIDField() + tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE, default=1) + id = models.UUIDField(default=uuid.uuid4) class TimeStamped(models.Model): diff --git a/tests/composite_pk/test_create.py b/tests/composite_pk/test_create.py index a007952f66..38ad9690fb 100644 --- a/tests/composite_pk/test_create.py +++ b/tests/composite_pk/test_create.py @@ -1,6 +1,7 @@ +from django.db import IntegrityError from django.test import TestCase, skipUnlessDBFeature -from .models import Tenant, User +from .models import Post, Tenant, User class CompositePKCreateTests(TestCase): @@ -8,7 +9,7 @@ class CompositePKCreateTests(TestCase): @classmethod def setUpTestData(cls): - cls.tenant = Tenant.objects.create() + cls.tenant = Tenant.objects.create(id=1) cls.user = User.objects.create( tenant=cls.tenant, id=1, @@ -151,3 +152,12 @@ class CompositePKCreateTests(TestCase): self.assertEqual(user.email, fields["defaults"]["email"]) self.assertEqual(user.email, f"user{user.id}@example.com") self.assertEqual(count + 1, User.objects.count()) + + def test_save_default_pk_not_set(self): + with self.assertNumQueries(1): + Post().save() + + def test_save_default_pk_set(self): + post = Post.objects.create() + with self.assertRaises(IntegrityError): + Post(tenant_id=post.tenant_id, id=post.id).save()