Opened 9 hours ago
Last modified 63 minutes ago
#36239 new Bug
ManyToManyField check error with invalid "to" when passing through/through_fields
Reported by: | Jordan Hyatt | Owned by: | |
---|---|---|---|
Component: | Core (System checks) | Version: | 5.1 |
Severity: | Normal | Keywords: | check |
Cc: | Jordan Hyatt | Triage Stage: | Unreviewed |
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 hereāhttps://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,
Note:
See TracTickets
for help on using tickets.
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.