I made a typo in defining a many to many through field in a model. See
below. In my ManyToManyField.through_field for "Stage" I have
"StageCatgeory" which is not correct the e and g are backwards.
See the stack trace below when running in v 1.8.4. it provides this
useless info... '''AttributeError: 'str' object has no attribute
'_meta'.'''
It wasn't until I tried running my app in 1.7.10, stack trace also below,
that I got useful feedback on the problem and was able to solve it.
'''Field specifies a many-to-many relation through model 'StageCatgeory',
which has not been installed.'''
This seems like a bug that 1.7 handled it and 1.8 did not.
{{{
class Stage(models.Model):
stage_id = models.AutoField(primary_key=True)
categories = models.ManyToManyField('Category',
through='StageCatgeory', related_name="stage_category")
class StageCategory(models.Model):
stage = models.ForeignKey('Stage', db_column='stage_id')
category = models.ForeignKey('Category', db_column='category_id')
class Category(models.Model):
category_id = models.AutoField(primary_key=True)
stage = models.ManyToManyField('Stage', through='StageCategory',
related_name="stage_category")
}}}
{{{
Django version 1.8.4, using settings 'my.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Performing system checks...
Unhandled exception in thread started by <function
check_errors.<locals>.wrapper at 0x102cbad90>
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/utils/autoreload.py", line 225, in wrapper
fn(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/core/management/commands/runserver.py", line 110, in
inner_run
self.validate(display_num_errors=True)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/core/management/base.py", line 468, in validate
return self.check(app_configs=app_configs,
display_num_errors=display_num_errors)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/core/management/base.py", line 481, in check
include_deployment_checks=include_deployment_checks,
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/core/checks/registry.py", line 72, in run_checks
new_errors = check(app_configs=app_configs)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/core/checks/model_checks.py", line 28, in
check_all_models
errors.extend(model.check(**kwargs))
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/db/models/base.py", line 1207, in check
errors.extend(cls._check_long_column_names())
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4
/site-packages/django/db/models/base.py", line 1648, in
_check_long_column_names
for m2m in f.rel.through._meta.local_fields:
AttributeError: 'str' object has no attribute '_meta'
}}}
{{{
Django version 1.7.10, using settings 'my.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Performing system checks...
Unhandled exception in thread started by <function wrapper at 0x103de3cf8>
Traceback (most recent call last):
File "/Users/me/virtualEnvs/myV2.7/lib/python2.7/site-
packages/django/utils/autoreload.py", line 222, in wrapper
fn(*args, **kwargs)
File "/Users/me/virtualEnvs/myV2.7/lib/python2.7/site-
packages/django/core/management/commands/runserver.py", line 105, in
inner_run
self.validate(display_num_errors=True)
File "/Users/me/virtualEnvs/myV2.7/lib/python2.7/site-
packages/django/core/management/base.py", line 362, in validate
return self.check(app_configs=app_configs,
display_num_errors=display_num_errors)
File "/Users/me/virtualEnvs/myV2.7/lib/python2.7/site-
packages/django/core/management/base.py", line 414, in check
raise CommandError(msg)
django.core.management.base.CommandError: System check identified some
issues:
ERRORS:
main.Stage.categories: (fields.E331) Field specifies a many-to-many
relation through model 'StageCatgeory', which has not been installed.
System check identified 1 issue (0 silenced).
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25292>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* type: Cleanup/optimization => Bug
* component: Uncategorized => Core (System checks)
* needs_tests: => 0
* needs_docs: => 0
Comment:
I couldn't reproduce the crash. Could you simplify your project to a
minimal example?
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:1>
Comment (by MarkusH):
I have yet to verify the ticket, but as a side note: I don't see a reason
why you have the `ManyToManyField` on `Category`, as this is automatically
added as a reverse relation by the `ManyToManyField` on `Stage`.
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:2>
* status: new => closed
* resolution: => needsinfo
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:3>
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:4>
Comment (by raratiru):
{{{
class Stage(models.Model):
stage_id = models.AutoField(primary_key=True)
class Category(models.Model):
category_id = models.AutoField(primary_key=True)
stage = models.ManyToManyField('Stage', through='StageCategory',
related_name="stage_category")
}}}
If we do not define the StageCategory table, the error is not understood
at all:
{{{
$ ./manage.py runserver
Performing system checks...
Unhandled exception in thread started by <function
check_errors.<locals>.wrapper at 0x7f3f16c930d0>
Traceback (most recent call last):
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/utils/autoreload.py", line 229, in wrapper
fn(*args, **kwargs)
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/core/management/commands/runserver.py", line 114, in
inner_run
self.validate(display_num_errors=True)
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/core/management/base.py", line 469, in validate
return self.check(app_configs=app_configs,
display_num_errors=display_num_errors)
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/core/management/base.py", line 482, in check
include_deployment_checks=include_deployment_checks,
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/core/checks/registry.py", line 72, in run_checks
new_errors = check(app_configs=app_configs)
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/core/checks/model_checks.py", line 28, in check_all_models
errors.extend(model.check(**kwargs))
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/db/models/base.py", line 1207, in check
errors.extend(cls._check_long_column_names())
File "/home/flyer/.virtualenvs/lived/lib/python3.4/site-
packages/django/db/models/base.py", line 1648, in _check_long_column_names
for m2m in f.rel.through._meta.local_fields:
AttributeError: 'str' object has no attribute '_meta'
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:5>
Comment (by timgraham):
Adding those models to a project, I still cannot reproduce a crash. Maybe
you could provide a sample project?
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:6>
Comment (by mlorant):
I just had the same problem when modifying a M2M relation (adding extra
data through intermediate model). Here is a translated example:
{{{
class Food(models.Model):
stuff_to_use = models.ManyToManyField(Bar, through='Ingredient')
class Meta:
app_label = 'legacy_app' # Bar and Ingredient does not have this
app_label
}}}
... where `Ingredient` is a classic M2M model with 2 FKs and some extra
data. The thing is `Ingredient` is not valid here and should be
`current_app.Ingredient`. It seems Django does not raises errors when the
model is not correctly resolved and treat the string passed as argument
instead of the supposed model....
Hope it helps to find the issue.
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:7>
Comment (by timgraham):
A full sample project to reproduce would be useful.
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:8>
* Attachment "django-error.tar.gz" added.
Sample project
* status: closed => new
* resolution: needsinfo =>
Comment:
I ran into this bug today using Django 1.9.7, I created a sample project
to reproduce it.
It doesn't happen when you use SQLite, I'm not sure about other databases.
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:9>
* easy: 0 => 1
* stage: Unreviewed => Accepted
Comment:
Oh, right, the `_check_long_column_names` method doesn't do anything on
SQLite so I couldn't reproduce there. We likely need to add a condition
similar to what appears under the "Skip nonexistent models" comment in
21130ce1a9c4fcbfce4c614be9e5408b43092bf0.
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:10>
* status: new => closed
* resolution: => fixed
Comment:
In [changeset:"baff4dd37dabfef1ff939513fa45124382b57bf8" baff4dd]:
{{{
#!CommitTicketReference repository=""
revision="baff4dd37dabfef1ff939513fa45124382b57bf8"
Fixed #25292 -- Fixed crash in ManyToManyField.through_fields check.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:11>
Comment (by Tim Graham <timograham@…>):
In [changeset:"f683bba6f6813e353c9391e993c015d74d77a1af" f683bba6]:
{{{
#!CommitTicketReference repository=""
revision="f683bba6f6813e353c9391e993c015d74d77a1af"
[1.10.x] Fixed #25292 -- Fixed crash in ManyToManyField.through_fields
check.
Backport of baff4dd37dabfef1ff939513fa45124382b57bf8 from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25292#comment:12>