From fcf916884d25ed430bd7cedaea2b10035c2aa3b6 Mon Sep 17 00:00:00 2001 From: Clifford Gama Date: Tue, 10 Mar 2026 17:47:18 +0200 Subject: Fixed #36973 -- Made fields.E348 check detect further clashes between managers and related_names. Clashes were only detected for self-referential relationships, i.e. ForeignKey("self"). Refs #22977. Bug in 6888375c53476011754f778deabc6cdbfa327011. Thanks JaeHyuckSa for the thorough review! --- django/db/models/fields/related.py | 40 +++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'django/db/models/fields') diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index f1bc664007..332a168a78 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -348,6 +348,24 @@ class RelatedField(FieldCacheMixin, Field): ) ) + # Check clash between reverse accessor and manager names on + # the target model. + if not rel_is_hidden: + manager_names = {m.name for m in rel_opts.managers} + if rel_name in manager_names: + errors.append( + checks.Error( + f"Related name '{rel_name}' for '{field_name}' " + f"clashes with the name of a model manager.", + hint=( + "Rename the model manager or change the related_name " + "argument in the definition for field '%s'." % field_name + ), + obj=self, + id="fields.E348", + ) + ) + return errors def db_type(self, connection): @@ -589,7 +607,6 @@ class ForeignObject(RelatedField): *self._check_to_fields_exist(), *self._check_to_fields_composite_pk(), *self._check_unique_target(), - *self._check_conflict_with_managers(), ] def _check_to_fields_exist(self): @@ -719,27 +736,6 @@ class ForeignObject(RelatedField): ] return [] - def _check_conflict_with_managers(self): - errors = [] - manager_names = {manager.name for manager in self.opts.managers} - for rel_objs in self.model._meta.related_objects: - related_object_name = rel_objs.name - if related_object_name in manager_names: - field_name = f"{self.model._meta.object_name}.{self.name}" - errors.append( - checks.Error( - f"Related name '{related_object_name}' for '{field_name}' " - "clashes with the name of a model manager.", - hint=( - "Rename the model manager or change the related_name " - f"argument in the definition for field '{field_name}'." - ), - obj=self, - id="fields.E348", - ) - ) - return errors - def deconstruct(self): name, path, args, kwargs = super().deconstruct() kwargs["on_delete"] = self.remote_field.on_delete -- cgit v1.3