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>
Related
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).
I have a flask project which allows users to create projects and to upload files to those projects. The URL structure looks something like /projects/<project_id>/documents/<document_id>.
My problem was that I was repeating /projects/ and /documents/ a lot for all the views that handled projects and documents (a view to list, a view to show, etc. etc.) so I thought that I could make life easier with blueprints. I decided that I could organize my code something like this:
app
projects
views.py
forms.py
__init__.py
documents
views.py
forms.py
__init__.py
views.py
__init__.py
run.py
However, there are forms (as well as pluggable views) that are used in both documents and projects.
My question is, how can I have code in common between my two blueprints? It's also possible that there's a way easier way to implement this (since all I really need is to avoid redundancy in typing out the URL), and I'd love to hear one.
Since you can have multiple documents per project and assuming that one document cannot be shared across multiple projects, I would suggest you only create a "Project" Blueprint and put the "Document" under it as a package. Something like:
app/
projects/
views.py
forms.py
__init__.py
documents/
views.py
forms.py
__init__.py
views.py
__init__.py
run.py
Now, under Projects/forms.py, you can add all the common code that is also relevant to Documents. Additionally, documents have their own forms.py but that could be very specific only to a document.
How can I import all models in the settings.py in INSTALLED_APPS? When i`m trying to insert some model there is an error occurred: "no models named app1_model"
-ProjectName
--ProjectName
---models
----__init__.py
----admin.py
----app_1_model
----....
----app_n_model
---templates
---__init__.py
---settings.py
---urls.py
---wsgi.py
--manage.py
^ Structure of project ^
The INSTALLED_APPS is for apps not for models. Models are classes that live within your app, usually in /«app_name»/models.py.
I think you have misunderstood how a Django project is structured. Try working through a tutorial example.
a typical structure:
/«project»/«app_name»/models.py
and in settings:
INSTALLED_APPS = [ ... '«app_name»' ... ]
Your path will contain the base project directory, so you can import your app where you need it.
And to use them:
from «app_name».models import *
Although it is always best not to import *, instead, name the classes you wish to import.
To answer the question in the comment:
If you don't like the idea of storing all your models in one file (even though it is normal to do this), you can create a module called models. To do this, create a directory called /«project»/«app_name»/models, inside it put __init__.py (to declare it as a module) and then create your files inside there. You then need to import your file contents into the module in __init__.py. You should read about Python modules to understand this.
To answer the second comment question:
To view models in admin, you should create an admin file with model admin objects.
And finally:
Please read through the tutorials to ensure you have a thorough understanding of Django. Otherwise you're wasting your own time!
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
This is a pretty simple django patterns question. My manager code usually lives in models.py, but what happens when models.py is really huge? Is there any other alternative pattern to letting your manager code live in models.py for maintainability and to avoid circular imports?
A question may be asked as to why models.py is so huge, but let's just assume it's size and breadth of utility is justified.
I prefer to keep my models in models.py and managers in managers.py (forms in forms.py) all within the same app. For more generic managers, I prefer to keep them in core.managers if they can be re-used for other apps. In some of our larger apps with models/modelname.py that will contains a manager and the model code which doesn't seem bad.
Your best bet with a large set of models is to use django modules to your advantage, and simply create a folder named models. Move your old models.py into this models folder, and rename it __init__.py. This will allow you to then separate each model into more specific files inside of this model folder.
You would then only need to import each model into your __init__.py's namespace.
So, for instance, you might want to separate it into:
yourapp/
models/
__init__.py # This file should import anything from your other files in this directory
basic.py # Just an example name
morespecificmodels.py # Just an example name
managers.py # Might want to separate your manager into this
Then your __init__.py can just be:
from basic import * # You should replace * with each models name, most likely.
from managers import YourManager # Whatever your manager is called.
This is the structure that I use when my model files get huge, however I try to separate things into more pluggable apps as often as possible - so this is rarely used by me.
Hope this helps.
I always place mine in managers.py. If you have a circular import issue remember that a) You can reference the model class for a manager at self.model, and b) You can do imports inside of functions.
What I did when building Django apps was to create a [modelname].py file with just the specific model code, manager code and sometimes form code and used an __init__.py file to import then all in the models directory. This helped me atleast in keeping it managable.