#25040 closed Bug (fixed)
get_related_models_recursive() cannot handle a model with a GenericFK
| Reported by: | Kai Richard König | Owned by: | Kai Richard König |
|---|---|---|---|
| Component: | Migrations | Version: | 1.8 |
| Severity: | Normal | Keywords: | migrations generic fk |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Example models.py:
from django.db import models
from django.contrib.contenttypes import generic
from django.db.migrations.state import get_related_models_recursive
class BaseModel(models.Model):
current_state = generic.GenericForeignKey()
get_related_models_recursive(BaseModel) # Exception!
Change History (12)
comment:1 by , 10 years ago
| Description: | modified (diff) |
|---|---|
| Needs tests: | set |
comment:2 by , 10 years ago
| Has patch: | set |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
comment:3 by , 10 years ago
comment:4 by , 10 years ago
The Exception is the same as when i run the above example.
Up until now i have been unable to reproduce the root cause, so I will explain what I have "seen" so far. (Fairly large project)
While walking the related_models in _related_models there is a relation that returns a real model
for related_model instead of the __fake__ one. Also I am seeing the meta containing the django.app registry instead of the state.apps any idea how to might end up there?
comment:5 by , 10 years ago
Stacktrace for completeness
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 30, in run_from_argv
super(Command, self).run_from_argv(argv)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 74, in execute
super(Command, self).execute(*args, **options)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/var/www/app/releases/1/app/django-sites/paessler/core/management/commands/bsxtest.py", line 19, in handle
TestCommand.handle(self, *test_labels, **options)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 90, in handle
failures = test_runner.run_tests(test_labels)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/test/runner.py", line 210, in run_tests
old_config = self.setup_databases()
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/test/runner.py", line 166, in setup_databases
**kwargs
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/test/runner.py", line 370, in setup_databases
serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/backends/base/creation.py", line 368, in create_test_db
test_flush=not keepdb,
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 120, in call_command
return command.execute(*args, **defaults)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 221, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 89, in migrate
for migration, _ in full_plan:
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 83, in mutate_state
operation.state_forwards(self.app_label, new_state)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/migrations/operations/models.py", line 53, in state_forwards
list(self.managers),
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 84, in add_model
self.reload_model(app_label, model_name)
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 125, in reload_model
related_models.update(get_related_models_recursive(rel_model))
File "/var/www/app/releases/1/venv-latest/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 60, in get_related_models_recursive
rel_app_label, rel_model_name = rel_mod._meta.app_label, rel_mod._meta.model_name
AttributeError: 'NoneType' object has no attribute '_meta'
comment:6 by , 10 years ago
I have seen this too.
In my case, I managed to pin it to an interaction between django-filer, django-cms and the migrations framework.
If I had a FilerImageField on a model that inherited CMSPlugin and attempted to migrate it, it would pull in a model in my code that had a GenericForeignKey, leading to the same interaction as described in this ticket.
I can validate that the sample code given here reproduces the issue in the smallest case.
comment:7 by , 10 years ago
| Needs tests: | unset |
|---|---|
| Triage Stage: | Unreviewed → Ready for checkin |
| Type: | Uncategorized → Bug |
comment:8 by , 10 years ago
| Summary: | #get_related_models_recursive cannot digest a Model with a GenericFK → get_related_models_recursive() cannot handle a model with a GenericFK |
|---|
comment:10 by , 10 years ago
| Resolution: | fixed |
|---|---|
| Status: | closed → new |
Reopening to backport to 1.8 as it's a regression.
get_related_models_recursive()is a private API that is only used in a context where there shouldn't be any generic foreign keys. I'm a bit reluctant to change this, as it can potentially hide other bugs which are more difficult to debug.Could you give some more context for the exception you're seeing? If you're seeing this exception in the migrations framework, and not because you're using this function on an actual model class as above, there must be some root cause that is a bug.
For further reference, it is extremely useful if you include the full traceback.