Opened 4 weeks ago

Closed 44 hours ago

Last modified 44 hours ago

#36973 closed Bug (fixed)

fields.E348 check should check against the accessor_name instead of the model name

Reported by: nick.ma@… 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 Shubh Rai, 4 weeks ago

Component: Core (System checks)Database layer (models, ORM)
Owner: set to Shubh Rai
Status: newassigned

comment:2 by Shubh Rai, 4 weeks ago

Cc: Shubh Rai added

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.

comment:3 by Clifford Gama, 4 weeks ago

Easy pickings: unset
Triage Stage: UnreviewedAccepted

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.

Version 0, edited 4 weeks ago by Clifford Gama (next)

comment:4 by Jacob Walls, 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 Jacob Walls, 3 days ago

Needs tests: unset
Triage Stage: AcceptedReady for checkin

Ah, it was already accounted for!

comment:6 by Jacob Walls, 3 days ago

Needs documentation: set
Severity: NormalRelease blocker
Triage Stage: Ready for checkinAccepted

Actually, this is a bug in 6.0, so we need a release note so we can backport before Tuesday.

comment:7 by Jacob Walls, 2 days ago

Owner: changed from Shubh Rai to Clifford Gama

comment:8 by Jacob Walls, 2 days ago

Needs documentation: unset
Triage Stage: AcceptedReady for checkin

comment:9 by Jacob Walls <jacobtylerwalls@…>, 44 hours ago

Resolution: fixed
Status: assignedclosed

In fcf91688:

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!

comment:10 by Jacob Walls <jacobtylerwalls@…>, 44 hours ago

In 4eb38f6:

[6.0.x] 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!

Backport of fcf916884d25ed430bd7cedaea2b10035c2aa3b6 from main.

Note: See TracTickets for help on using tickets.
Back to Top