mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
Fixed #22977 -- Added check for clash between model manager and model field's related_name
.
New check added on model related fields to check if the `related_name` conflicts with the respective model's manager name. With thanks to kswiat, loic, felixxm and russellm
This commit is contained in:
parent
1860a1afc9
commit
0cb31fda4e
@ -581,6 +581,7 @@ class ForeignObject(RelatedField):
|
||||
*super().check(**kwargs),
|
||||
*self._check_to_fields_exist(),
|
||||
*self._check_unique_target(),
|
||||
*self._check_conflict_with_managers(),
|
||||
]
|
||||
|
||||
def _check_to_fields_exist(self):
|
||||
@ -679,6 +680,28 @@ class ForeignObject(RelatedField):
|
||||
]
|
||||
return []
|
||||
|
||||
def _check_conflict_with_managers(self):
|
||||
errors = []
|
||||
for manager in self.opts.managers:
|
||||
for rel_objs in self.model._meta.related_objects:
|
||||
manager_name = manager.name
|
||||
related_object_name = rel_objs.name
|
||||
if manager_name == related_object_name:
|
||||
field_name = f"{self.model._meta.object_name}.{self.name}"
|
||||
errors.append(
|
||||
checks.Error(
|
||||
f"Related name for '{field_name}' clashes with "
|
||||
f"manager: '{related_object_name}' name.",
|
||||
hint=(
|
||||
"Rename manager name or related_name "
|
||||
"in conflicted field"
|
||||
),
|
||||
obj=self,
|
||||
id="fields.E341",
|
||||
)
|
||||
)
|
||||
return errors
|
||||
|
||||
def deconstruct(self):
|
||||
name, path, args, kwargs = super().deconstruct()
|
||||
kwargs["on_delete"] = self.remote_field.on_delete
|
||||
|
@ -327,6 +327,8 @@ Related fields
|
||||
* **fields.E339**: ``<model>.<field name>`` is not a foreign key to ``<model>``.
|
||||
* **fields.E340**: The field's intermediary table ``<table name>`` clashes with
|
||||
the table name of ``<model>``/``<model>.<field name>``.
|
||||
* **fields.E341**: ``<model>``.``related_name`` must be different than the
|
||||
``<model>``'s manager name.
|
||||
* **fields.W340**: ``null`` has no effect on ``ManyToManyField``.
|
||||
* **fields.W341**: ``ManyToManyField`` does not support ``validators``.
|
||||
* **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same
|
||||
|
@ -1407,6 +1407,29 @@ class ExplicitRelatedQueryNameClashTests(SimpleTestCase):
|
||||
)
|
||||
|
||||
|
||||
@isolate_apps("invalid_models_tests")
|
||||
class RelatedQueryNameClashWithManagerTests(SimpleTestCase):
|
||||
def test_clash_between_related_query_name_and_manager(self):
|
||||
class Author(models.Model):
|
||||
authors = models.Manager()
|
||||
mentor = models.ForeignKey(
|
||||
"self", related_name="authors", on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
Author.check(),
|
||||
[
|
||||
Error(
|
||||
"Related name for 'Author.mentor' clashes with manager: "
|
||||
"'authors' name.",
|
||||
hint="Rename manager name or related_name in conflicted field",
|
||||
obj=Author._meta.get_field("mentor"),
|
||||
id="fields.E341",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@isolate_apps("invalid_models_tests")
|
||||
class SelfReferentialM2MClashTests(SimpleTestCase):
|
||||
def test_clash_between_accessors(self):
|
||||
|
Loading…
Reference in New Issue
Block a user