I've just started working on a codebase that the team I've joined is updating from using Django 1.4 to Django 1.8. Along with that change, it's being restructured into separate apps, and the layout is being changed in various ways.
INSTALLED_APPS has some apps, let's call them foo and bar, but their models.py files have been put into db subdirectories, that is foo/db/models.py.
Those models can be accessed from code (for example views) with from foo.db.models import SomeModel, and that seems to work.
However, from my reading of https://docs.djangoproject.com/en/1.8/ref/applications/#initialization-process, particularly stage 2, models defined in foo/db/models.py rather than foo/models.py won't be found during application loading, which will cause a variety of issues.
Is it possible to support this non-standard location of models.py with a custom AppConfig, or in some other way?
To clarify, I think trying to have models.py in a non-standard location is a bad idea; I'm after confirmation to help make my argument to the rest of the team.
The models submodule name is hardcoded, and it's the only module that is imported by Django during that step of the initialization process.
However, you can easily import your models inside your models.py file to ensure your models are imported at the correct time. If all your app's models are defined or imported in foo.db.models, you can simply use this:
# foo/models.py
from foo.db.models import *
Related
I have a bunch of REST views and a bunch of data transfers posted from templates that needs to be cleaned. I am wondering where to put all the sanitizing code and processing code should go: views.py or models.py ? Am I missing some secret tricks that I don't know about? (like usage of model.manager) ?
Currently I kept the models clean with object creation and update. Views is nicely organized with strictly REST views. But as the project grows, more and more code, especially handling of data that has accumulated. (views.py file had grown in size to 150lines) Should I put them in another file. If so, is that ok to pass the whole "request" to that file? (along with having to import models and possibly sessions and messages)
I have implemented my django apps like this:
In models.py: just add the definition of the models and some code usefull for the Signals because in my application will work with other models
In view.py: here i add the code usefull for manage the form for the frontend and create the json necessary for the API call to external app
of course you can split the code in other files and call the functions when needed like fuctions.py or options.py
from .functions import calc
External app with Rest Framework: here is the CORE of the application, where i'll call the models, where all the logic is available
This is how i use it, by the way is always better use the view.py for write the code.
Some Tips about The Model View Controller pattern in web applications
I read the documents, but could not understand how removing the need of models.py will improve the system.
The benefits are listed in bullet form here. You can see that not requiring models.py is just one of stated benefits of the new approach.
Applications can run code at startup, before Django does anything else, with the ready() method of their configuration.
Application labels are assigned correctly to models even when they’re defined outside of models.py. You don’t have to set app_label explicitly any more.
It is possible to omit models.py entirely if an application doesn’t have any models.
Applications can be relabeled with the label attribute of application configurations, to work around label conflicts.
The name of applications can be customized in the admin with the verbose_name of application configurations.
The admin automatically calls autodiscover() when Django starts. You can consequently remove this line from your URLconf.
Django imports all application configurations and models as soon as it starts, through a deterministic and straightforward process. This should make it easier to diagnose import issues such as import loops.
In addition, various bugs having to do with app loading were fixed under the rubric of app-loading refactor. For example, it used to be that some parts of the system looked at the INSTALLED_APPS from front-to-back and others back-to-front. Now the order is consistent throughout the system.
As for models.py, it doesn't make sense to use that to mark applications when it's not necessary to have models to be an application (for example, a reusable app can just have templates, say, or management commands). You used to have to include an empty models.py file; now you can leave it out entirely.
I have quite a big django project which has a lot of applications and a lot of models.
In order to avoid circular imports several models modules must be used:
app/models.py
app/models_add.py
app/models_aux.py
and so on.
Each time I have to make a migration I have to write
from app.models_add import Model
in the app/models.py in order for South to track the model's changes.
This seems to be quite annoying because there are a lot of changes in models.
The question is: is there a way to point South which modules/files to track?
You could try setting the app_label on the Meta class of your model.
class Meta:
app_label = "app"
Also try setting your directory structure to:
app/models/__init__.py
app/models/add.py
That should tell everything to initialize properly. This is what I recently did, but for backwards compatibility in other areas of my project I import everything in models/__init__.py
I am writing an app in Django which has a few sitewide fixed objects I need to instantiate which, for one reason or another, can't be fixtures.
For example, some (e.g. Permissions) I can't hardcode a PK for because I can't be sure that they'll be loaded in a certain order (and if I use pk=null then I get an IntegrityError if they exist already.)
Others (e.g. Sites) depend on values in settings.py. Edit: These need to run each time the project is deployed, otherwise I could use South's data migrations as per super9's suggestion below.
Since these are Django models, they're not directly related to any of the apps in my project. It would make the most sense to load them in settings.py but that results in a circular import. It works in urls.py but putting the loading code there seems hackish and out-of-place.
I looked into hooking a receiver into post_syncdb as follows:
#receiver(post_syncdb)
def create_groups_and_permissions(sender, **kwargs):
print "Creating groups and permissions"
u_ct = ContentType.objects.get(model="user")
Group.objects.get_or_create(name='Group 1')
Permission.objects.get_or_create(name="Perm 1", codename="perm_1", content_type=u_ct)
However, since I'm using South, per the documentation it only sends post_syncdb when the table is first created. I could call syncdb manually after each time I migrate but would prefer not to.
I am nearly resolved to put them in urls.py or the most closely related app's models.py but thought I'd check here to see if there's an accepted way of loading fixed objects which can't be loaded as fixtures.
Have you checked out data migrations in south yet? http://south.aeracode.org/docs/tutorial/part3.html
Sounds like it might be what you need.
Where would I put project based views that I've created for my django project?
For example - things like JSONResponseMixin?
I'd like to put them into a folder like my_project/views/generic/ajax.py - but I'm not sure how I would then call this within apps in my project?
Something like from my_project.views.generic.ajax import JSONResponseMixin doesn't work because it says there is no app "views"...
In django it is probaby best to follow the django way so a project is divided into apps, apps contain there modules (models, views, urls ...), you can however create your own local/utility/contrib app, it can just be a folder with an init.py and your modules. If you want to partition it further into directories (each sub directory I believe would need it's own init.py), you would have to then include it (the apps root folder) in your INSTALLED_APPS tuple and from there should be able to (afaik) import the module as you would have done for anything else.
Edit: Just found this answer to a somewhat related question, probably worth a read