Project Structure

Here’s a README section explaining the proposed project structure and its advantages over the default Django layout:

Project Structure

django-rest-framework

The default Django project layout generated by django-admin startproject can be confusing. To address these issues and create a more maintainable and scalable project structure, I am a big fan of this proposed project template (mirror here) instead:

.
├── apps/
│   └── example/                    # A django rest app
│       ├── api/
│       │   ├── v1/                 # Only the "presentation" layer exists here.
│       │   │   ├── __init__.py
│       │   │   ├── serializers.py
│       │   │   ├── urls.py
│       │   │   └── views.py
│       │   ├── v2                  # Only the "presentation" layer exists here.
│       │   │   ├── __init__.py
│       │   │   ├── serializers.py
│       │   │   ├── urls.py
│       │   │   └── views.py
│       │   └── __init__.py
│       ├── fixtures/               # Constant "seeders" to populate your database
│       ├── management/
│       │   ├── commands/           # Try and write some database seeders here
│       │   │   └── command.py
│       │   └── __init__.py
│       ├── migrations/
│       │   └── __init__.py
│       ├── templates/              # App-specific templates go here
│       ├── tests/                  # All your integration and unit tests for an app go here.
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── models.py
│       ├── services.py             # Your business logic and data abstractions go here.
│       ├── urls.py
│       └── views.py
├── common/                         # An optional folder containing common "stuff" for the entire project
├── config/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── deployments/                    # Isolate Dockerfiles and docker-compose files here.
├── docs/
│   ├── CHANGELOG.md
│   ├── CONTRIBUTING.md
│   ├── deployment.md
│   ├── local-development.md
│   └── swagger.yaml
├── requirements/
│   ├── common.txt                  # Same for all environments
│   ├── development.txt             # Only for a development server
│   ├── local.txt                   # Only for a local server (example: docs, performance testing, etc.)
│   └── production.txt              # Production only
├── static/                         # Your static files
├── .env.example                    # An example of your .env configurations. Add necessary comments.
├── .gitignore                      # https://github.com/github/gitignore/blob/main/Python.gitignore
├── entrypoint.sh                   # Any bootstrapping necessary for your application
├── manage.py
├── pytest.ini
└── README.md

This project structure offers clearer naming conventions, reducing confusion, and provides a more intuitive layout for API development with built-in versioning support, making it better suited for modern Django REST API projects. It also still supports traditional Django apps with HTML views by allowing you to place templates in the app-specific templates/ directory and keeping views.py in the app root.

Async tasks with Celery

see Using Celery with Django

Logging in with Email

Use a custom auth backend as per this post:

created an appname.auth module with:

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
 
 
class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if user.check_password(password):  # type: ignore
                return user
        return None
 

In site’s settings.py:

AUTHENTICATION_BACKENDS = ['appname.auth.EmailBackend']