Here’s the traceback that should have been provided with the report in the first place
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'
It looks like you ran into and edge case with the through_fields
model checks (a feature rarely used). The following patch resolves the issue (against main
)
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,
But it’s debatable if through
or through_fields
checks should be run in the first place when to
is invalid as they will necessary be as well. Applying the above produces the following check failures
SystemCheckError: System check identified some issues:
ERRORS:
app.Bar.foos: (fields.E300) Field defines a relation with model 'Fo', which is either not installed, or is abstract.
app.Bar.foos: (fields.E307) The field app.Bar.foos was declared with a lazy reference to 'app.fo', but app 'app' doe not provide model 'fo'.
app.Bar.foos: (fields.E339) 'FooBar.foo' is not a foreign key to 'Fo'.
app.FooBar: (fields.E336) The model is used as an intermediate model by 'app.Bar.foos', but it does not have a foreign key to 'Bar' or 'app.Fo'.