Django-Specific Standards

These are some best practices to use when developing Django projects.

General

Models

Blank vs Null

Django's ORM maps models and querysets back to a relational database. Most fields can be defined with options to allow NULL values (null=True) or blank values (blank=True). What's important to remember is that null relates to the database itself, whereas blank relates to field validation only. Typically, NULL values indicate that a field on a model wasn't set to anything, and so there's no value to put in the corresponding database column. However, allowing TextFields or CharFields to be both null and blank leads to a situation where two values could represent the absence of data. For this reason, you should not use null=True for these fields (or subclasses of these fields, such as EmailField).

The database does not care if a TextField or CharField is blank or not, however. This is only taken into account when validating input when creating a model instance (or deserializing input from an API.) In almost all circumstances, you should generally set text-type fields to blank=True if a field is allowed to have no value, and default='' in order to fill the field when no input is specified.

Routes

Project Layout

In general, we stick to the basic Django project layout. Your root repository folder will typically contain configuration files like the main README.md, Dockerfile, fabfile, .drone.yml, etc, as well as the main project filter generated with the startproject command. Inside the project folder is another folder of the same name, where settings.py, wsgi.py and the root urls.py live, known as the configuration folder. The manage.py command also lives here.

When you use the startapp command, it will create a folder with models.py, views.py, admin.py, and tests.py files inside. Try to limit each app to a specific feature, and only create those models needed to implement that feature.

Settings

Since we primarily use Django combined with Django REST Framework (DRF) to build RESTful API servers, some of the default Django applications and middleware are unecessary and add memory and performance overhead for unneeded features. It is therefore recommended to remove the following default apps and middleware from the INSTALLED_APPS and MIDDLEWARE_CLASSES settings, respectively:

# Unnecessary apps
'django.contrib.sessions'
'django.contrib.messages'
'django.contrib.staticfiles'

# Unnecessary middleware
'django.contrib.sessions.middleware.SessionMiddleware'
'django.middleware.csrf.CsrfViewMiddleware'
'django.contrib.auth.middleware.SessionAuthenticationMiddleware'
'django.contrib.messages.middleware.MessageMiddleware'

Note: If you are using DRF's built-in browsable API feature, it relies on Django's session-based authentication to work. You'll need to leave in django.contrib.sessions in INSTALLED_APPS as well as django.contrib.sessions.middleware.SessionMiddleware and django.contrib.auth.middleware.SessionAuthenticationMiddleware in MIDDLEWARE_CLASSES.

Django REST Framework

For more specifics around building a Django-based API project, check our DRF best practices.