Tips for a better Django project structure

2021-07-28 4 min read

I can't be sure which kind of structure is best, but I can share some tips for an easy to manage and clear to understand Django project structure. In this post, we'll try to go beyond the simple Django project structure. It'll be useful for beginners.

For all examples, assume that the project is named "elmadev" and is a blog project.

1. A separate folder for apps

Usually we see a structure with separate folders for each application in a Django project. One folder per application in the home dir of the project? I think this makes the structure unnecessarily complex.

We can keep all the apps in a single folder named apps:

β”œβ”€β”€ apps              <---- attention here
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ authors
β”‚Β Β  └── posts
β”œβ”€β”€ elmadev
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ asgi.py
β”‚Β Β  β”œβ”€β”€ settings.py
β”‚Β Β  β”œβ”€β”€ urls.py
β”‚Β Β  └── wsgi.py
└── manage.py

In the settings.py file, we can add that apps folder to the path:

sys.path.append(str(BASE_DIR / 'apps'))

With this way, we can still import any modules like we do before:

from authors.views import AuthorDetailView
from posts.views import PostDetailView

2. Custom name for the main folder

I think it's more clear to use a generic name, rather than naming the main folder the same as the project name.

$ django-admin startproject elmadev

The above command creates a structure like below:

elmadev
β”œβ”€β”€ elmadev  # <--- attention here
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ asgi.py
β”‚Β Β  β”œβ”€β”€ settings.py
β”‚Β Β  β”œβ”€β”€ urls.py
β”‚Β Β  └── wsgi.py
└── manage.py

But, the structure we want is as follows:

elmadev
β”œβ”€β”€ main  # <--- attention here
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ asgi.py
β”‚Β Β  β”œβ”€β”€ settings.py
β”‚Β Β  β”œβ”€β”€ urls.py
β”‚Β Β  └── wsgi.py
└── manage.py

if you are going to create a new project, you can easily achieve this using the following command:

$ django-admin startproject main

But if you want to have that structure in an already created project, try this:

  1. Rename the folder elmadev to main.
  2. Update the paths containing elmadev according to the new folder name main:
    • manage.py:9, wsgi.py:14, asgi.py:14: elmadev.settings > main.settings
    • main/settings.py:52: ROOT_URLCONF = 'elmadev.urls' > ROOT_URLCONF = 'main.urls'
    • main/settings.py:70: WSGI_APPLICATION = 'elmadev.wsgi.application' > WSGI_APPLICATION = 'main.wsgi.application'

3. Multiple settings.py files for different development stages

You can use different settings.py files for development, testing and deployment stages. There are various approaches for this. Let's go through an easy-to-understand example.

Since we changed the name of our main project folder in the previous example, it is now main.

  1. Name the settings.py file in the main folder as base.py.

  2. Create a folder named settings in the main folder and move the base.py file into it. Don't forget to also create an empty __init__.py file in the settings folder.

  3. Create a new file named development.py and add the following codes:

    from base import *
    
    DEBUG = True
    # ...
    
  4. Here you can override all the settings you want to change for the development stage, like in the DEBUG = True line.

  5. Change the main.settings path in the asgi.py and the wsgi.py files to main.settings.base.

  6. For example, if you define DJANGO_SETTINGS_MODULE = 'main.settings.development variable in the virtual environment you use for development, Django will use the development.py module while in this env.

4. Separate requirements.txt files:

You can have multiple requirements.txt files like requirements.txt and requirements-dev.txt and in the requirements-dev.txt file, you can import the content of the requirements.txt file like below:

-r requirements.txt

With this way, when you install dependencies with the command pip install -r requirements-dev.txt, it will also install the dependencies listed in the requirements.txt file.


Many more suggestions could be added, but the article is getting long. Maybe I'll add more tips in the future.

Date: 2021-07-28
Categories: pythondevelopment
Tags: django