I would like to know if there is a way to include/import the models.py from the project directory to multiple apps without copying the model in each app. Thank you!
Every app must have its own models.py present in the app folder.You have models.py in an app folder you can write the following import statement in any file of your project:
from myapp.models import model_to_import
If you have models.py outside any app folder or any other folder, then make sure that folder contains an (with two underscores)init(with two underscores).py file and just write the following in the file you want to import:
from folder_name import models
from models import model_to_import
You could create an app which contains any models which you need project-wide, e.g.
python manage.py startapp projectcore
and then
from projectcore.models import MyModel
as needed.
But probably better to listen to Ludwik and try to restructure if you can!
You are not meant to put models directly on a project level in Django. Every model have to be associated with a particular app. On the other hand you can import models between apps.
If you feel a need for a project level models it just means you haven't partitioned your functionality into apps properly. There shouldn't be any reason to have "project level models" (or "project level views" for that matter). You just need to split the functionality into separate apps.
Let's say you are designing an intranet website for a school. You would have one app that deals with students' accounts, and another app generating timetables, and yet another one for an internal message board, etc.. Every app defines its own models (there are no "project level models"), but apps can import each others models (so message board posts can have a ForeignKey field pointing at student from the "students" app).
Related
I am a a beginner learning django rest framework. I want to know if it is a good idea to create all my classes in one model file (model.py) of my app. Is it a good idea?
I generally start off having all of the models in a single models.py file. As the project gets larger and the app more complicated I'll sometimes end up breaking it out into multiple files (generally in a models directory).
An example of this is our user's app. We have multiple sets of users with different permissions in our website. Admin Users, Tour leaders, Suppliers, etc... Each one of these have been broken up into its own file to keep the logic contained.
users/
models/
__init__.py
base.py // Stores the abstract User model used across all Users
leaders.py // Stores specific models four Tour Leaders
suppliers.py // Stores specific models for Suppliers
money.py // Stores models related to how we pay Tour Leaders (lots of logic here)
views.py
forms.py
urls.py
This allows us to contain all of the business logic into specific files, making it easier for developers to find what they want.
In our __init__.py file we import all of the models.
from users.models.base import *
from users.models.leaders import *
from users.models.suppliers import *
from users.models.money import *
You can, but if you have quite a few models it's better to create a folder called models/ inside your app, and put your models in there. You will also need to make a __init__.py file to import your models into for migrations to work (Django only expects to import app.models, and the __init__.py file handles that).
So your folder will look like:
models/
__init__.py
modelA.py
modelB.py
modelC.py
And your __init__.py will look like:
from .modelA import <modelName>
from .modelB import <modelName>
from .modelC import <modelName>
I am learning Django. My background is from PHP and Java with experience using Model View Controller frameworks. I have always had a seperate file for each of my views, models, and templates - but the Django tutorial only mentions having one views.py and models.py.
That seems to be okay if you have a small application — what if you would like to organise your views and models by their purpose? For example, a Projects view and a Milestones view. I would hope that you would not have to create another Python package (app) for each view module:
python manage.py startapp projects
python manage.py startapp milestones
I can assume that you can have a milestones.py and a projects.py for your views and models instead of a generic views.py and models.py? Then models can be imported where necessary into the views, and requests routed to specific views?
There is no problem with having multiple files containing views and models.
In fact all you need is module views and module models. In python the module is either file that ends with .py or folder that contains file __init__.py.
The app can look something like:
app_folder
- views
| - __init__.py
| - some_view.py
| - some_other_view.py
- models
| - __init__.py
| - some_model.py
| - some_other_model.py
The models/__init__.py should look similar to code below (for submodules to be looked up by django at all).
from some_model import SomeModel
from some_other_model import SomeOtherModel
The only difference from the common approach is to have app_label defined in models:
class SomeModel(models.Model):
class Meta:
app_label = 'app_folder'
Check out the related doc entry.
Update:
The development version docs say you won't have to define app_label in this case any more starting with 1.7 release.
Afterword:
In fact if you need to do that it usually means your app is too big and you should split it into several apps. Most people who come to django are afraid of having many small apps. The more third party apps you read through the more you realize app should solve one and only one problem. In your example having app milestones seems perfectly legit.
I am refactoring a Django application. Specifically, I have an application with a big models.py file and I am trying to split it into a bunch of small files, like
myapp/
models/
__init__.py
somemodels.py
someothers.py
somemore.py
...
and in models/__init__.py I import all models from all other files so that I do not have to change client code.
The problem is that Django now complains about table names. Table for model Foo used to be myapp_foo, but it seems that Django now looks for a table myapp.models_foo. That is, it seems that it uses as prefix the package where the models are defined instead of their application (of course myapp.models is not registered as a Django application).
I know I could manually set the table name for each and every models, but is there a way to avoid this and tell Django that these models are actually part of myapp?
Use Meta.app_label
Think of this:
You create a CMS of some sort, which asks you for an application name and a csv file for that application.
Then it automatically creates that app on the fly, creates the required model.py based on the csv columns, activates the admin page for it and allows only you to have the full permission to this new table via django admin, then it inserts the the app into the url.py and creates the view.py for it as well.
Then all you'd have to do is upload a csv, name your app and whola!, you have an admin page to play with.
Now, is there anyway to create an app or at least a model.py out of a csv file in django or is there any django-app that can do this?
Note: Look beyond (./manage.py inspectdb > models.py)
While this does not involve creating an actual models.py and application, you may want to look into dynamically creating Model classes at runtime. You could have "meta" models that store the information on the dynamic models, and then have your CSV view import the data into those models, create the classes, and register them with the admin. Or something like that.
Creating an actual application directory, with models.py, views.py, and so on, is fairly easy (just create the directory, create the files, and write formatted strings to them based on the CSV data). Editing the project's settings.py and urls.py, and reloading the modules, wouldn't be too difficult either. But, I wouldn't trust automatically generated Django applications without first looking at them.
I've noticed that in order for me to define models, I need to do something like:
python manage.py startapp app_name
Is there anyway to avoid this convention and be able to create a models.py directly in the top level site that django-admin.py has created for me? Sometimes I'm building a site that can be put together in literally 15 minutes thanks to Django. I don't see the need for complexity of having an additional app built and a modified settings.py just for a form model or something similar.
Not really. The django admin programs expect app/models.py file names.