From cbdf128cb316bccf9ca3b3b4966e57bd050bfc8a Mon Sep 17 00:00:00 2001 From: Hal Blackburn Date: Tue, 4 Nov 2025 05:58:46 +0000 Subject: [PATCH] [5.2.x] Fixed #36704 -- Fixed system check error for proxy model with a composite pk. Proxy models subclassing a model with a CompositePrimaryKey were incorrectly reporting check errors because the check that requires only local fields to be used in a composite pk was evaluated against the proxy subclass, which has no fields. To fix this, composite pk field checks are not evaluated against proxy subclasses, as none of the checks are applicable to proxy subclasses. This also has the benefit of not double-reporting real check errors from an invalid superclass pk. Thanks Clifford Gama for the review. Backport of 74564946c3b42a2ef7d087047e49873847a7e1d9 from main. --- django/db/models/base.py | 2 +- docs/releases/5.2.8.txt | 3 +++ tests/composite_pk/test_checks.py | 35 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/django/db/models/base.py b/django/db/models/base.py index d7d207901b..77353121f5 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1782,7 +1782,7 @@ class Model(AltersData, metaclass=ModelBase): meta = cls._meta pk = meta.pk - if not isinstance(pk, CompositePrimaryKey): + if meta.proxy or not isinstance(pk, CompositePrimaryKey): return errors seen_columns = defaultdict(list) diff --git a/docs/releases/5.2.8.txt b/docs/releases/5.2.8.txt index a75db9cbc8..62cb32f55c 100644 --- a/docs/releases/5.2.8.txt +++ b/docs/releases/5.2.8.txt @@ -16,3 +16,6 @@ Bugfixes * Fixed a bug in Django 5.2 where ``QuerySet.first()`` and ``QuerySet.last()`` raised an error on querysets performing aggregation that selected all fields of a composite primary key. + +* Fixed a bug in Django 5.2 where proxy models having a ``CompositePrimaryKey`` + incorrectly raised a ``models.E042`` system check error. diff --git a/tests/composite_pk/test_checks.py b/tests/composite_pk/test_checks.py index c33f2ee2eb..21796aa871 100644 --- a/tests/composite_pk/test_checks.py +++ b/tests/composite_pk/test_checks.py @@ -268,3 +268,38 @@ class CompositePKChecksTests(TestCase): ), ], ) + + def test_proxy_model_can_subclass_model_with_composite_pk(self): + class Foo(models.Model): + pk = models.CompositePrimaryKey("a", "b") + a = models.SmallIntegerField() + b = models.SmallIntegerField() + + class Bar(Foo): + class Meta: + proxy = True + + self.assertEqual(Foo.check(databases=self.databases), []) + self.assertEqual(Bar.check(databases=self.databases), []) + + def test_proxy_model_does_not_check_superclass_composite_pk_errors(self): + class Foo(models.Model): + pk = models.CompositePrimaryKey("a", "b") + a = models.SmallIntegerField() + + class Bar(Foo): + class Meta: + proxy = True + + self.assertEqual( + Foo.check(databases=self.databases), + [ + checks.Error( + "'b' cannot be included in the composite primary key.", + hint="'b' is not a valid field.", + obj=Foo, + id="models.E042", + ), + ], + ) + self.assertEqual(Bar.check(databases=self.databases), [])