#1179 closed defect (fixed)
[magic-removal] Models not in INSTALLED_APPS should raise ImportError
| Reported by: | Adrian Holovaty | Owned by: | Adrian Holovaty |
|---|---|---|---|
| Component: | Metasystem | Version: | magic-removal |
| Severity: | normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
In trunk, if you try to import a model that isn't in INSTALLED_APPS, Django will raise ImportError. This lets you do the following:
try:
from django.models.foo import bar
except ImportError:
bar = None
# ...
if bar is not None:
bar_objects = bar.get_list()
else:
bar_objects = []
The magic-removal branch doesn't yet have this feature.
Change History (6)
comment:1 by , 20 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
comment:2 by , 20 years ago
Adrian, the patch you've added forces all models to be in models.py, as noted in #1437. Could you revert the patch? The functionality in trunk is a remnant of the old magic way of doing things. You can do it this way now (with or without the patch):
from myproj.myapp.models import bar from django.db.models.loading import get_models if not bar in get_models(): bar = None
comment:3 by , 20 years ago
| Resolution: | fixed |
|---|---|
| Status: | closed → reopened |
Just to clarify my argument a bit: the behaviour you've re-added is definitely magic of the bad variety -- you don't expect in normal Python that doing an import should fail when it is perfectly possible to import the name. In other words, 'models not in INSTALLED_APPS should not raise ImportError' is magic-removal's response to this behaviour I would have thought.
comment:4 by , 20 years ago
I second that. I've just started porting my apps over to magic-removal today and hit this right away. It was working perfectly well in trunk. I am using this method for model inheritance so that the parent model classes don't have tables created for them in the DB.
in myproj/myapp/basemodel.py I have:
class BaseModel(models.Model): # fields
and in myproj/myapp/models.py I have:
from myproj.myapp.basemodel import BaseModel
class MyModel(BaseModel):
# more fields
Then I get this:
>>> from myproj.myapp.models import MyModel
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/path/to/myproj/myapp/models.py", line 2, in ?
from myproj.myapp.basemodel import BaseModel
File "/path/to/myproj/myapp/basemodel.py", line 5, in ?
class BaseModel(models.Model):
File "/path/to/django/django/db/models/base.py", line 33, in __new__
raise ImportError, "INSTALLED_APPS must contain %r in order for you to use this model." % re.sub('\.models$', '', mod)
ImportError: INSTALLED_APPS must contain 'myproj.myapp.basemodel' in order for you to use this model.
comment:5 by , 20 years ago
Another possibility is to add an 'installed' attribute onto a models '_meta', at the same point in the code where you are currently throwing an ImportError. So the code to check a model would look like this:
from myproj.myapp.models import Bar if not Bar._meta.installed: Bar = None
comment:6 by , 20 years ago
| Resolution: | → fixed |
|---|---|
| Status: | reopened → closed |
(In [2406]) magic-removal: Fixed #1179 -- Models not in INSTALLED_APPS now raise ImportError