#36973 closed Bug (fixed)
fields.E348 check should check against the accessor_name instead of the model name
| Reported by: | Owned by: | Clifford Gama | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.0 |
| Severity: | Release blocker | Keywords: | System checks, fields.E348, related_name |
| Cc: | nick.ma@…, Shubh Rai | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
when running manage.py I hit erroneous fields.E348 check. The system check is supposed to examine if ManyToOne/ManyToMany field <related_name> for <model>.<field name> clashes with the name of a model manager. However, instead of checking the related_name (i.e. <fieldname>_set or manually set related_name=<related_name>) it gets the actual field name of the foreign key.
As shown in the original check function below
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
it compares a model's managers' name and its related object field name.
related_object_name = rel_objs.name
Patch:
It should use the .accessor_name instead of .name
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index f1bc664007..a3ef912a8e 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -723,7 +723,7 @@ class ForeignObject(RelatedField):
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
+ related_object_name = rel_objs.accessor_name
if related_object_name in manager_names:
field_name = f"{self.model._meta.object_name}.{self.name}"
errors.append(
Change History (10)
comment:1 by , 4 weeks ago
| Component: | Core (System checks) → Database layer (models, ORM) |
|---|---|
| Owner: | set to |
| Status: | new → assigned |
comment:2 by , 4 weeks ago
| Cc: | added |
|---|
comment:3 by , 4 weeks ago
| Easy pickings: | unset |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
While investigating this ticket, I discovered that the patch added in #22977 only identifies a clash between an accessor and a manager if the relationship is self-referential. The attempt to fix that issue made it easier to understand the issue reported here. I opened an alternative PR to fix both issues.
comment:4 by , 3 days ago
| Needs tests: | set |
|---|
I think we can add one test case for the issue discovered in review, but otherwise this is good to go.
comment:5 by , 3 days ago
| Needs tests: | unset |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
Ah, it was already accounted for!
comment:6 by , 3 days ago
| Needs documentation: | set |
|---|---|
| Severity: | Normal → Release blocker |
| Triage Stage: | Ready for checkin → Accepted |
Actually, this is a bug in 6.0, so we need a release note so we can backport before Tuesday.
comment:7 by , 45 hours ago
| Owner: | changed from to |
|---|
comment:8 by , 44 hours ago
| Needs documentation: | unset |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
I have made a pr: https://github.com/django/django/pull/20846 . Please feel free to tell me any changes that are required , any feedback would be appreciated.