1
0
mirror of https://github.com/django/django.git synced 2025-10-16 10:19:11 +00:00

[6.0.x] Fixed #36611, Refs #36580 -- Added system check for multicolumn ForeignObject in Meta.indexes/constraints/unique_together.

ForeignObjects with multiple `from_fields` are not supported in these
options.

Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>

Backport of 5b51e6f759f2ba993219347435149173c756c478 from main.
This commit is contained in:
Sarah Boyce 2025-09-19 16:27:51 +02:00 committed by Natalia
parent 86e7406cfb
commit 0fa339ce71
4 changed files with 69 additions and 0 deletions

View File

@ -2220,6 +2220,20 @@ class Model(AltersData, metaclass=ModelBase):
id="models.E048",
)
)
elif (
isinstance(field.remote_field, ForeignObjectRel)
and field not in cls._meta.local_concrete_fields
and len(field.from_fields) > 1
):
errors.append(
checks.Error(
f"{option!r} refers to a ForeignObject {field_name!r} with "
"multiple 'from_fields', which is not supported for that "
"option.",
obj=cls,
id="models.E049",
)
)
elif field not in cls._meta.local_fields:
errors.append(
checks.Error(

View File

@ -443,6 +443,9 @@ Models
* **models.E048**: ``constraints/indexes/unique_together`` refers to a
``CompositePrimaryKey`` ``<field name>``, but ``CompositePrimaryKey``\s are
not supported for that option.
* **models.E049**: ``constraints/indexes/unique_together`` refers to a
``ForeignObject`` ``<field name>`` with multiple ``from_fields``, which is
not supported for that option.
Management Commands
-------------------

View File

@ -295,6 +295,10 @@ Models
don't support it (MySQL and MariaDB), the fields are marked as deferred to
trigger a refresh on subsequent accesses.
* Using a :ref:`ForeignObject <cpk-and-relations>` with multiple
``from_fields`` in Model indexes, constraints, or :attr:`unique_together
<django.db.models.Options.unique_together>` now emits a system check error.
Pagination
~~~~~~~~~~

View File

@ -166,6 +166,54 @@ class UniqueTogetherTests(SimpleTestCase):
],
)
def test_pointing_to_foreign_object(self):
class Reference(models.Model):
reference_id = models.IntegerField(unique=True)
class ReferenceTab(models.Model):
reference_id = models.IntegerField()
reference = models.ForeignObject(
Reference,
from_fields=["reference_id"],
to_fields=["reference_id"],
on_delete=models.CASCADE,
)
class Meta:
unique_together = [["reference"]]
self.assertEqual(ReferenceTab.check(), [])
def test_pointing_to_foreign_object_multi_column(self):
class Reference(models.Model):
reference_id = models.IntegerField(unique=True)
code = models.CharField(max_length=1)
class ReferenceTabMultiple(models.Model):
reference_id = models.IntegerField()
code = models.CharField(max_length=1)
reference = models.ForeignObject(
Reference,
from_fields=["reference_id", "code"],
to_fields=["reference_id", "code"],
on_delete=models.CASCADE,
)
class Meta:
unique_together = [["reference"]]
self.assertEqual(
ReferenceTabMultiple.check(),
[
Error(
"'unique_together' refers to a ForeignObject 'reference' with "
"multiple 'from_fields', which is not supported for that option.",
obj=ReferenceTabMultiple,
id="models.E049",
),
],
)
@isolate_apps("invalid_models_tests")
class IndexesTests(TestCase):