#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 , 10 years ago
| Component: | Uncategorized → Core (System checks) |
|---|---|
| Type: | Cleanup/optimization → Bug |
comment:2 by , 10 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 , 10 years ago
| Resolution: | → needsinfo |
|---|---|
| Status: | new → closed |
comment:4 by , 10 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 , 10 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 , 10 years ago
Adding those models to a project, I still cannot reproduce a crash. Maybe you could provide a sample project?
comment:7 by , 10 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?