From d83fb782d33aa7aaa1b2c995c648a59eddb46047 Mon Sep 17 00:00:00 2001 From: Bendeguz Csirmaz Date: Mon, 13 Jan 2025 19:33:47 +0800 Subject: [PATCH] Fixed #36092 -- Disallowed non-local fields in composite primary keys. --- django/db/models/base.py | 2 ++ tests/composite_pk/test_checks.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/django/db/models/base.py b/django/db/models/base.py index ae2a494747..a4d5a0d553 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1803,6 +1803,8 @@ class Model(AltersData, metaclass=ModelBase): hint = f"{field_name!r} field may not set 'null=True'." elif field.generated: hint = f"{field_name!r} field is a generated field." + elif field not in meta.local_fields: + hint = f"{field_name!r} field is not a local field." else: seen_columns[field.column].append(field_name) diff --git a/tests/composite_pk/test_checks.py b/tests/composite_pk/test_checks.py index c803d521cc..c33f2ee2eb 100644 --- a/tests/composite_pk/test_checks.py +++ b/tests/composite_pk/test_checks.py @@ -247,3 +247,24 @@ class CompositePKChecksTests(TestCase): ), ], ) + + def test_composite_pk_cannot_include_non_local_field(self): + class Foo(models.Model): + a = models.SmallIntegerField() + + class Bar(Foo): + pk = models.CompositePrimaryKey("a", "b") + b = models.SmallIntegerField() + + self.assertEqual(Foo.check(databases=self.databases), []) + self.assertEqual( + Bar.check(databases=self.databases), + [ + checks.Error( + "'a' cannot be included in the composite primary key.", + hint="'a' field is not a local field.", + obj=Bar, + id="models.E042", + ), + ], + )