DEV Community

Cover image for Mastering Django: Best Practices for Writing High-Quality Web Applications
pratyush
pratyush

Posted on

Mastering Django: Best Practices for Writing High-Quality Web Applications

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

GitHub logo 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

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:

  1. Virtual Environment folder
  2. .env files
  3. static/ folder
  4. 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 your settings.py file

  • The .env file should look like this:

DATABASE_NAME=postgres
DATABASE_USER=adam
...
Enter fullscreen mode Exit fullscreen mode
  • 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"),
    }
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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
Enter fullscreen mode Exit fullscreen mode

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
'''
...
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
sankalp1999 profile image
Sankalp

Very informative Pratyush. Keep writing!

Collapse
 
pratyushcode profile image
pratyush

Thanks for the shoutout brdr!

Collapse
 
alireza4130 profile image
Alireza

Great

Collapse
 
pratyushcode profile image
pratyush

Thanks brdr

Collapse
 
shrihacker profile image
Shri Hacker

Great write up ! super organized and i especially like the best practices repo

Collapse
 
pratyushcode profile image
pratyush

Thank you shri sir! means a lot

Collapse
 
vodiylik profile image
Shukrullo Turgunov

Django Cookiecutter