Django is a popular web framework for building high-quality web applications. It provides a robust set of tools and features that enable developers to build web applications quickly and efficiently.
However, building a high-quality web application requires more than just knowing the basics of Django. To build a robust, scalable, and maintainable application, developers need to follow best practices and use Django's features correctly.
In this blog post, we'll explore four essential practices that will help you keep your project organized, secure, and production-ready.
We'll cover how to create and update a .gitignore
file, how to manage sensitive information using .env
files, how to use the Django settings package to manage project settings, and finally, we'll share some standard practices to keep your project production-ready. Let's get started!
NOTE: To highlight these design and configuration changes, I have authored a repo
pratyzsh/django-best-practices
. Please feel free to raise a pull request and support the project
beeryani / django-best-practices
Best practices every Django developer should follow from start to finish
Django Best Practices
This repository provides a collection of best practices for developing Django web applications. These practices are based on industry standards and can help you write more robust, maintainable, and scalable Django code.
Table of Contents
- Getting Started
- Project Structure
- Environment Configuration
- PostgreSQL Database Connection
- Security
- Testing
- Deployment
- Contributing
- License
Getting Started
First clone the repository from Github and switch to the new directory:
$ git clone https://github.com/pratyzsh/django-best-practices
$ cd django-best-practices
Activate the virtualenv for your project.
$ source django_env/bin/activate
Install project dependencies:
$ pip install -r requirements.txt
Then simply apply the migrations:
$ python manage.py migrate
You can now run the development server:
$ python manage.py runserver
Project Structure
A well-organized project structure is key to writing maintainable code. This section provides recommendations for organizing your Django project.
Environment Configuration
Managing environment variables is important for keeping your application secure and flexible. This section covers how to…
1. Create and update .gitignore
file
We need .gitignore files to exclude certain files and directories from being tracked by Git. This helps to keep our repositories clean and avoids cluttering them with unnecessary files. Additionally, it improves repository performance and security by preventing sensitive or large files from being accidentally committed.
Some common files you should always aim to exclude from commit history using .gitignore
:
- Virtual Environment folder
-
.env
files -
static/
folder - Database files, in Django, we have
db.sqlite3
database as default which needs to be excluded
For Django, you can use this base template and extend it based on your project requirements.
2. Add .env
files to manage sensitive information
.env
files are used to securely store sensitive information such as passwords and API keys. They keep this information separate from source code and configuration files. Additionally, they allow for easy switching between different environments without modifying code.
In case of Django, we have a bunch of sensitive information to deal with, like SECRET_KEY
, DATABASE_NAME
, DATABASE_PASS
and so on.
Here's an example how we can do this in Django.
Create
.env
file in the same directory as yoursettings.py
fileThe
.env
file should look like this:
DATABASE_NAME=postgres
DATABASE_USER=adam
...
- After storing the secrets in the above file, we can configure the
settings.py
file like this:
import environ
env = environ.Env()
# reading .env file
environ.Env.read_env()
SECRET_KEY = env("SECRET_KEY")
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': env("DATABASE_NAME"),
'USER': env("DATABASE_USER"),
'PASSWORD': env("DATABASE_PASSWORD"),
'HOST': env("DATABASE_HOST"),
'PORT': env("DATABASE_PORT"),
}
}
Refer to the repository to understand the implementation details.
3. Create different settings.py
for different deployment environments
When you're developing a Django project, you'll typically have different settings depending on the environment you're working in, such as development, testing, staging, and production.
Few key reasons:
Security: Production environments have different security requirements than development or testing environments. Using different settings files ensures that security measures like HTTPS and limited database permissions are properly implemented.
Performance: Production environments have different performance requirements than development or testing environments. Using different settings files ensures that performance measures like caching and load balancing are properly implemented.
Debugging: Debugging in production is different than debugging in development or testing. Different logging or error reporting tools might be needed, which can be specified in different settings files.
Customisation: Different environments might have different requirements or configurations that need to be customised, such as email or SMS providers. Using different settings files ensures that these Customisation are properly implemented for each environment.
To manage this, there are multiple approaches that you can take. I learnt a lot from this article and the approach I borrowed is creating a separate settings/
package and change the reference in manage.py
file.
The final project structure should look like this:
\
+-- sampleproject
| +-- settings.py #default settings file
| +-- ...
+-- settings #package with base.py as the new default settings file
| +-- __init__.py
| +-- base.py
| +-- development.py
| +-- production.py
Once you have created a separate folder and added your separate setting files, make changes in the manage.py
file.
...
def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.base")
'''
reference changed to settings/base.py in the above line
'''
...
Once you have made these changes, you can independently manage all environments by changing their respecting settings.
In order to run the application using development.py
in the example mentioned above, either we can change the manage.py
based on our project requirement but you also run this command to extend settings dynamically.
python manage.py runserver --settings=settings.development
This is a fast way to toggle between environments before initiating the deployment process.
Refer to the repository to understand the implementation details.
As a final note, one thing I have personally found to be very useful in ensuring these best practices are followed, is to ensure proper naming, formatting and linting of my code.
You can check out my other blog, Streamlining Your Python Workflow with Black, Ruff, GitHub Actions, and Pre-Commit Hooks which is also used in the repository. Do check out the blog and repository. Like and share if you find this valuable.
Implement these and experience a blazing fast workflow ✨✨✨
Top comments (7)
Very informative Pratyush. Keep writing!
Thanks for the shoutout brdr!
Great
Thanks brdr
Great write up ! super organized and i especially like the best practices repo
Thank you shri sir! means a lot
Django Cookiecutter