#25292 closed Bug (fixed)
"'str' object has no attribute '_meta'" crash in ManyToManyField.through_fields check
Reported by: | thbarrons | Owned by: | nobody |
---|---|---|---|
Component: | Core (System checks) | Version: | 1.8 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
version 1.8 doesn't handle an error properly in ManyToManyField.through_fields and gives useless feedback when performing system checks
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).
Attachments (1)
Change History (13)
comment:1 by , 9 years ago
Component: | Uncategorized → Core (System checks) |
---|---|
Type: | Cleanup/optimization → Bug |
comment:2 by , 9 years ago
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
.
comment:3 by , 9 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
comment:4 by , 9 years ago
Summary: | doesn't handle an error properly in ManyToManyField.through_fields → "'str' object has no attribute '_meta'" crash in ManyToManyField.through_fields check |
---|
comment:5 by , 9 years ago
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'
comment:6 by , 9 years ago
Adding those models to a project, I still cannot reproduce a crash. Maybe you could provide a sample project?
comment:7 by , 9 years ago
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.
comment:9 by , 9 years ago
Resolution: | needsinfo |
---|---|
Status: | closed → new |
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.
comment:10 by , 9 years ago
Easy pickings: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
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.
I couldn't reproduce the crash. Could you simplify your project to a minimal example?