Opened 6 months ago
Closed 6 months ago
#36239 closed Bug (fixed)
ManyToManyField check error with invalid "to" when passing through/through_fields
Reported by: | Jordan Hyatt | Owned by: | JaeHyuckSa |
---|---|---|---|
Component: | Core (System checks) | Version: | 5.1 |
Severity: | Normal | Keywords: | check |
Cc: | Jordan Hyatt | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
Bug was discussed in the forums herehttps://forum.djangoproject.com/t/manytomanyfield-error-message-with-incorrect-to-argument/39394.
Basically, if an invalid "to" argument is passed to ManyToManyField while also passing the through/through_fields arguments the check framework crashes giving unhelpful error message/traceback.
Minimal reproduceable example:
class Foo(Model): pass class Bar(Model): foos = ManyToManyField( to = "Fo", # NOTE incorrect "to" argument through = 'FooBar', through_fields = ('bar', 'foo') ) class FooBar(Model): foo = ForeignKey('Foo', on_delete=CASCADE) bar = ForeignKey('Bar', on_delete=CASCADE)
Traceback:
File "django/core/checks/registry.py", line 88, in run_checks new_errors = check(app_configs=app_configs, databases=databases) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "django/core/checks/model_checks.py", line 36, in check_all_models errors.extend(model.check(**kwargs)) ^^^^^^^^^^^^^^^^^^^^^ File "django/db/models/base.py", line 1691, in check *cls._check_fields(**kwargs), ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "django/db/models/base.py", line 1828, in _check_fields errors.extend(field.check(from_model=cls, **kwargs)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "django/db/models/fields/related.py", line 1400, in check *self._check_relationship_model(**kwargs), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "django/db/models/fields/related.py", line 1676, in _check_relationship_model related_model._meta.object_name, ^^^^^^^^^^^^^^^^^^^ AttributeError: 'str' object has no attribute '_meta'
Proposed Patch:
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 6a9cb12a90..dd4c09a4e3 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1707,13 +1707,18 @@ def _check_relationship_model(self, from_model=None, **kwargs): and getattr(field.remote_field, "model", None) == related_model ): + related_object_name = ( + related_model + if isinstance(related_model, str) + else related_model._meta.object_name + ) errors.append( checks.Error( "'%s.%s' is not a foreign key to '%s'." % ( through._meta.object_name, field_name, - related_model._meta.object_name, + related_object_name, ), hint=hint, obj=self,
Change History (17)
comment:1 by , 6 months ago
comment:2 by , 6 months ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:3 by , 6 months ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:4 by , 6 months ago
Needs tests: | set |
---|---|
Patch needs improvement: | set |
comment:5 by , 6 months ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:6 by , 6 months ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:7 by , 6 months ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:8 by , 6 months ago
Hi Django Team,
I noticed that PR #19248 is currently open for this issue, but some unresolved test failures remain.
Is the current contributor still working on it, or would it be okay for me to assist in fixing the remaining issues?
Thanks!
comment:9 by , 6 months ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:10 by , 6 months ago
Hey Django Team,
I’d love to jump on ticket #36239 (ManyToManyField crash with invalid to). Can you assign it to @Amaan-ali03? I’ve dug into the issue and want to implement the fix.
Issue:
An invalid to (e.g., "Fo") with through/through_fields crashes with AttributeError: 'str' has no '_meta' because related_model isn’t handled properly.
Proposed Fix:
Update _check_relationship_model in django/db/models/fields/related.py with a type check:
related_object_name = ( related_model if isinstance(related_model, str) else related_model._meta.object_name ) errors.append( checks.Error( f"'{through._meta.object_name}.{field_name}' is not a foreign key to '{related_object_name}'.", obj=self, ) )
comment:11 by , 6 months ago
Needs tests: | unset |
---|---|
Patch needs improvement: | unset |
comment:12 by , 6 months ago
Fixes #36239: Prevents AttributeError: 'str' object has no attribute '_meta'
in ManyToManyField
when to
is invalid with through
/through_fields
.
- Issue: The validation framework assumed
related_model
was always resolved, causing a crash when it remained a string. - Fix: If
related_model
is a string, we handle it gracefully in_check_relationship_model
. - Test: Added test in
tests/model_fields/tests.py
to confirm expected error messages (E300
,E339
). - Impact: Prevents crashes and ensures Django correctly raises validation errors instead.
follow-up: 14 comment:13 by , 6 months ago
We appreciate your interest Tanishq but there's no need to step in here.
JaeHyuckSa's PR is already passing the full suite with any failures and is only awaiting a final review.
comment:14 by , 6 months ago
Replying to Simon Charette:
We appreciate your interest Tanishq but there's no need to step in here.
JaeHyuckSa's PR is already passing the full suite with any failures and is only awaiting a final review.
okay, thanks for informing me, I will continue contributing in other issues, if that's fine?
comment:15 by , 6 months ago
sure, try to find tickets that don't already have any active owner and ready for review PRs.
comment:16 by , 6 months ago
Triage Stage: | Accepted → Ready for checkin |
---|
Hey Django Team,
I’d love to work on this issue!
Requesting to assign this ticket to @Amaan-ali03 to implement the proposed fix for the ManyToManyField error with an invalid "to" argument.
Proposed Approach:
Identify the Issue: The bug occurs when an invalid "to" argument is passed to ManyToManyField along with through and through_fields, causing an AttributeError due to improper handling of the related_model variable.
Proposed Solution: Update the _check_relationship_model method in django/db/models/fields/related.py to include a type check for related_model. Instead of directly accessing related_model._meta, the code should verify if related_model is a string and handle it accordingly to avoid the crash.