Reputation: 32290
Having a Model in file MyApp/models/Artwork.py
:
class Artwork(models.Model):
class Meta:
verbose_name = _('Artwork')
verbose_name_plural = _('Artworks')
def __init__(self, *args, **kwargs):
super(Artwork, self).__init__(*args, **kwargs)
objects = ArtworkManager()
And an action in file: MyApp/functions/actions.py
from MyApp.models import Artwork
import pprint;
def lock_artwork(request, id):
pprint.pprint(Artwork)
try:
art = Artwork.objects.get(pk=id)
except ObjectDoesNotExist:
raise Http404()
In MyApp/models/__init__.py
:
from .Artwork import Artwork
I get the curious error of not having the attribute objects
in my model, which is there.
Stacktrace:
web_1 | <module 'MyApp.models.Artwork' from '/app/MyApp/models/Artwork.py'>
web_1 | Internal Server Error: /en/artwork/lock/2/
web_1 | Traceback (most recent call last):
web_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
web_1 | response = get_response(request)
web_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
web_1 | response = self.process_exception_by_middleware(e, request)
web_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
web_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
web_1 | File "/app/MyApp/functions/actions.py", line 72, in lock_artwork
web_1 | art = Artwork.objects.get(pk=id)
web_1 | AttributeError: module 'MyApp.models.Artwork' has no attribute 'objects'
Something obvious I'm missing?
Upvotes: 1
Views: 1589
Reputation: 73460
For all of Django's automagic (migrations, model loading, ...) to work, models have to live in the namespace of their app's models
! It does not matter whether that is a plain module or a package. What we often do to separate models in different modules within an app is the following:
MyApp
models
__init__.py
artwork # not the name of any model inside it!
other
And inside the __init__.py
, you import all the models from the submodules:
# __init__.py
from .artwork import Artwork
from .other import OtherModel, YetAnotherModel
That way, models.Artwork
resolves to the actual model and is picked up by all of django's internal magic. You can now also import the Artwork
model straight from MyApp.models
anywhere in your code:
# e.g. some views.py
from MyApp.models import Artwork
On a side note: 10 models in a file is not that much. I would only split that if there are clear semantic separations and no circular references (in which case you could argue for separate apps to begin with). If dozens of models and hundreds of lines in a file should are an issue, you might want to look for a better IDE ;-)
Upvotes: 1