Lazy loading of related fields does not work for non-loaded models
|Reported by:||Andreas Pelme||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||1.5|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||yes|
There is a problem with the lazy loading mechanism of related fields.
Steps to reproduce (reproduced with 1.4 and 1.5):
$ django-admin.py startproject lazy_model_loading $ cd lazy_model_loading/ lazy_model_loading $ python manage.py startapp foo lazy_model_loading $ python manage.py startapp bar lazy_model_loading $ echo "class Foo(models.Model): bar = models.ForeignKey('bar.Bar')" >> foo/models.py lazy_model_loading $ echo "class Bar(models.Model): pass" >> bar/models.py lazy_model_loading $ echo "INSTALLED_APPS = ['foo', 'bar']" >> lazy_model_loading/settings.py
This is the expected behavior (this is the way everything should work)
lazy_model_loading $ python manage.py shell --plain Python 2.7.2 (default, Jun 20 2012, 16:23:33) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from foo.models import Foo >>> Foo() <Foo: Foo object>
However, when running python directly, the issue is triggered:
lazy_model_loading $ DJANGO_SETTINGS_MODULE=lazy_model_loading.settings python Python 2.7.2 (default, Jun 20 2012, 16:23:33) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from foo.models import Foo >>> Foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/andreas/.virtualenvs/removeme/lib/python2.7/site-packages/django/db/models/base.py", line 397, in __init__ val = field.get_default() File "/Users/andreas/.virtualenvs/removeme/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1038, in get_default if isinstance(field_default, self.rel.to): TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
The difference here is that manage.py shell calls get_models which forces all models to load (which, judging by the comment is an old workaround for another lazy load bug):
If get_models is removed from the shell management command - it will show the same problem.
This is probably the same bug as described here:
http://stackoverflow.com/questions/14386536/instantiating-django-model-raises-typeerror-isinstance-arg-2-must-be-a-class (altough the accepted answer does not seem to be 100 % correct - I am pretty sure it does this bug does not depend on settings.DEBUG)
This bug can lead to very hard-to-debug problems since it depends on the the implicit import order before the model being initiated. The exception that is thrown is also not very helpful.
I would be happy to provide a fix, but I am not sure where to start fixing this... Pointers would be appreciated.
Change History (12)
comment:3 Changed 4 years ago by
|Summary:||Lazy loading of related fields does not work → Lazy loading of related fields does not work for non-loaded models|