Django with a simple project structure / Django /

Introduction

You can find a draft Django Enhancement Proposal that aims to improve on the base django startproject structure here. While this is cooking, you can start using a simpler structure for your django projects, to match the one in the DEP.

project
├── manage.py
└── project
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    ├── wsgi.py
    ├── apps.py
    ├── models.py
    └── migrations
        └── __init__.py

Generating the project

We will use the standard django management command to create the initial project structure:

$ django-admin startproject project
$ tree project
project
├── manage.py
└── project
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Adding the missing files and configuration

Let's first add the apps.py file:

# project/apps.py
from django.apps import AppConfig

class ProjectConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'project'

And then the models.py file:

$ touch project/models.py

The last step is to add our project app to the INSTALLED_APPS list in the settings.py file:

INSTALLED_APPS = [
    'project',
    ...
]

You can now run some tests. Add a model to the models.py file and run the migration commands:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
$ python manage.py makemigrations project
$ python manage.py migrate
$ python manage.py shell
>>> from project.models import Post
>>> Post.objects.create(title='Hello', content='World')

You have a working django project with a simple structure.

Bonus 1 - Nesting Apps

You can also have your apps nested inside the project folder:

project
├── manage.py
└── project
    ├── ...
    └── app1
        └── ...

You can do so by moving said apps into the project folder

$ python manage.py startapp app1
$ mv app1 project/

and updating the name of the app in the apps.py file:

# project/app1/apps.py
from django.apps import AppConfig

class App1Config(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'project.app1'  # updated

then adding the app to the INSTALLED_APPS list in the settings.py file:

INSTALLED_APPS = [
    'project',
    'project.app1',  # added
    ...
]

You now have a nested app structure where you can use the project.models as your "Common" app and the nested apps for your project-specific apps.

Bonus 2 - Creating your own templates

You can also create your own templates for the startproject command. Which you can use to generate the project structure you want by simply passing in the -t flag:

$ django-admin startproject project -t my_template

You can look through the official django project templates here. After you've settled on a template, you can suffix the python files with -tpl and use the variables fed to the files (such as {{ project_name }}) to generate the files you want.

Here's an example of a custom project template that uses the simple structure in this post.