#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 , 9 years ago
Description: | modified (diff) |
---|---|
Needs tests: | set |
comment:2 by , 9 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:3 by , 9 years ago
comment:4 by , 9 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 , 9 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 , 9 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 , 9 years ago
Needs tests: | unset |
---|---|
Triage Stage: | Unreviewed → Ready for checkin |
Type: | Uncategorized → Bug |
comment:8 by , 9 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 , 9 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.