Home > Back-end >  How to split django 'models.py', 'views.py', 'serializers.py' files in
How to split django 'models.py', 'views.py', 'serializers.py' files in

Time:10-23


Hello,
For educational purposes, I am building a django app with multiple models and relationships.
According to the official tutorial and many implementations I found online, the database models and serializers as well as views are all defined in single files: "models.py", "serializers.py", and "views.py".
So, the project directory looks as follows:
> my_app
    > migrations
    > __init__.py
    > admin.py
    > models.py
    > apps.py
    > serializers.py
    > tests.py
    > urls.py
    > views.py

Depending on how many models are included in the app, those files may grow to hundreds or even thousands lines of code. As a result, developing and maintaining the application becomes extremely challenging. I would like to split these files so that every model (and coresponding serializer and view) will be defined in a separate per-model file.
As follows:

> my_app
    > migrations
    > models
        > __init__.py
        > model1.py
        > model2.py
        > model3.py
        > model4.py
    > serializers
        > __init__.py
        > model1_serializers.py
        > model2_serializers.py
        > model3_serializers.py
        > model4_serializers.py
    > views
        > __init__.py
        > model1_views.py
        > model2_views.py
        > model3_views.py
        > model4_views.py
    > __init__.py
    > admin.py
    > apps.py
    > tests.py
    > urls.py

I encountered some difficulties in splitting these files and have not yet found an optimal solution.

The Problem

In order to define a serializer -> corresponding model should be imported.
And in order to define a view -> corresponding model and serializers should be imported.

There are some difficulties importing objects from models/files located in the same level as the parent directoriey. For example: Importing model to serializers/model1_serializers.py results an error

from models.model1 import Model1 # error: Unresolved reference 'models'
from my_app.models.model1 import Model1 # error: Unresolved reference 'my_app'

What I have tried

  1. Mark project directory as source in pycharm - After marking "my_app" folder as source the following import works. But running the code outside of pycharm (cmd for example) results import errors.
from models.model1 import Model1
  1. Adding the project direcrtory to sys.path - sys.path contains a list of directories that the interpreter will search in for the required module. So adding the following lines should make import possible (in file my_app/views/model1_views.py), but it doesnt work, pycharm still marks the import lines as errors. Do you know where is my mistake?
import os
from sys import path

path.append(os.path.dirname(os.path.dirname(__file__)))

from my_app.models.model1 import Model1

I would very appreciate if you could explain my mistake and propose a solution for spliting those files, thank you!

CodePudding user response:

Don't know if it's advisable to create a new view and serializer file for each model, it kinda makes things messy as the app grows.

If it's just the model you can do what's mentioned in the Django docs

Where you can remove the models.py file and instead create a models directory and have your different model files there as such: myapp/models/, myapp/models/first_model.py etc.

But if you basically want to separate concerns you can create a new Django app for each function/concern, like this:

> my_app_one
    > migrations
    > __init__.py
    > admin.py
    > models.py
    > apps.py
    > serializers.py
    > tests.py
    > urls.py
    > views.py
> my_app_two
    > migrations
    > __init__.py
    > admin.py
    > models.py
    > apps.py
    > serializers.py
    > tests.py
    > urls.py
    > views.py

This should fix your import issue.

CodePudding user response:

Instead of making multiple models, serializers and views files make multiple apps!

That way is more organized and also you can link apps together and import whatever you like from other applications!

CodePudding user response:

You need to add a package __init__.py file in my_app, and import from there:
from my_app import models

models.Model1.objects.all()

This tells Python that my_app is a package, and makes the submodules importable from it.
You thus structure your project as:
my_app/
    __init__.py
    models/
        __init__.py
        model1.py
        model2.py
        ...
    serializers/
        __init__.py
        ...
    views/
        __init__.py
        ...
    ...
And then import from the my_app package.
Note that often models, serializers and views are grouped per application, not per model. So you make app1, app2, etc. subpackages, and place the models, serializers and views for that app in there.
  • Related