After years of working with different Django projects, I noticed some excellent design patterns and packages that helps maintain the project's code quality, simplicity, readability, maintainability, reliability, and testing.
This is a compilation of patterns and libraries that I learned over the years to help build a robust Django application fast.
App
- Django3, framework for building fast and clean web applications
- Postgres, open-source object-relational database for persisting data
- Redis, in-memory data structure store used as a database, cache, and message broker
- GraphQL/Graphene, query language for the API and a runtime for fulfilling those queries with existing data
- Python decouple, helps you to organize your project settings on environment variables
Background and scheduled tasks:
- Celery, task queue with to process background tasks
- Celery Beat (Periodic tasks), scheduler to kick off tasks at regular intervals
Testing:
- Pytest, test framework that makes easy to write small and scalable tests
- Faker, generates fake data for you
- Freezegun, allows your tests to freeze or travel through time
- Factory Boy, fixture replacement tool that aims to easy-to-use factories for complex objects
- Pytest-Mock, plugin that provides a
mocker
fixture that is a wrapper around the mock package
Development
- Docker, build and run the entire application in docker containers
- Watchdog, python file change monitor to reload django fast when you modify a python file
- Isort, sort and organize your imports automatically
- Black, code-formatter that automatically restructure your code
- Flak8, tool for styled guide enforcement
- Pre-commit, framework for managing and maintaining pre-commit hooks
- Repository Pattern
- Almost every query should live in
core/db/repository/
- Avoid writing queries on Django's Manager/QuerySet.
- The repository functions should return a list of instances, instead of a QuerySet. This makes easy caching data.
- Almost every query should live in
- Single Django app layer
- It's recommend to write the entire application inside the
core
- Avoid creating new django apps
- It's recommend to write the entire application inside the
- One model per file
- Each model should have its own file in
core/db/models/
- Each model should have its own file in
- Service layer
- All business logic should be added in
core/services/
- All business logic should be added in
Clone the project
$ git clone git@github.com:marcosflp/django-boilerplate.git project_name
$ cd project_name
Install pre-commit
$ pip install pre-commit
$ pre-commit install
- Running the app:
$ docker compose up
- Running tests:
docker compose exec web pytest
- Create a new virtual env
- Install the dependencies:
$ pip install -r requirements.txt
- You have to install and run the postgres server. Also, configure the database settings
- Run migrations:
$ python manage.py migrate
- Running the server:
$ python manage.py runserver
- Running tests:
$ pytest
Automatically deploy this project to AWS with Terraform and Ansible!
AWS - With admin access to create EC2, RDS instances and network resources
$ export AWS_ACCESS_KEY_ID=
$ export AWS_SECRET_ACCESS_KEY=
Terraform
$ export TF_VAR_AWS_DB_PASSWORD_DJANGO_BOILERPLATE=
Setup
$ cd deployment/terraform
$ terraform init
$ terraform apply
Create and set all Django production's settings env variables
$ cp deployment/config_files/.env.production.example deployment/config_files/.env.production
Update Nginx domain name at
$ deployment/config_files/nginx/sites-enabled/django_boilerplate.org.conf
Update gunicorn path at
$ deployment/config_files/gunicorn.service
Set the hosts at
$ deployment/config_files/inventory
Setup the entire Django app and Webservers
$ cd deployment/ansible
$ ansible-playbook -i inventory playbook_setup_ubuntu.yml playbook_setup_django.yml playbook_setup_webservers.yml --tags="setup"
Deploy updates
$ cd deployment/ansible
$ ansible-playbook -i inventory playbook_setup_ubuntu.yml playbook_setup_django.yml playbook_setup_webservers.yml --tags="deploy"