Coding style | Django documentation (original) (raw)

Please follow these coding standards when writing code for inclusion in Django.

Pre-commit checks

pre-commit is a framework for managing pre-commit hooks. These hooks help to identify simple issues before committing code for review. By checking for these issues before code review it allows the reviewer to focus on the change itself, and it can also help to reduce the number of CI runs.

To use the tool, first install pre-commit and then the git hooks:

/ 

$ python -m pip install pre-commit $ pre-commit install

...> py -m pip install pre-commit ...> pre-commit install

On the first commit pre-commit will install the hooks, these are installed in their own environments and will take a short while to install on the first run. Subsequent checks will be significantly faster. If an error is found an appropriate error message will be displayed. If the error was with black or isort then the tool will go ahead and fix them for you. Review the changes and re-stage for commit if you are happy with them.

Python style

Allowed

f"hello {user}"
f"hello {user.name}"
f"hello {self.user.name}"

Disallowed

f"hello {get_user()}"
f"you are {user.age * 365.25} days old"

Allowed with local variable assignment

user = get_user()
f"hello {user}"
user_days_old = user.age * 365.25
f"you are {user_days_old} days old"
f-strings should not be used for any string that may require translation, including error and logging messages. In general format() is more verbose, so the other formatting methods are preferred.
Don’t waste time doing unrelated refactoring of existing code to adjust the formatting method.

Imports

future

from future import unicode_literals

standard library

import json
from itertools import chain

third-party

import bcrypt

Django

from django.http import Http404
from django.http.response import (
Http404,
HttpResponse,
HttpResponseNotAllowed,
StreamingHttpResponse,
cookie,
)

local Django

from .models import LogEntry

try/except

try:
import yaml
except ImportError:
yaml = None
CONSTANT = "foo"
class Example: ...

Template style

Follow the below rules in Django template code.

View style

Model style

Don’t do this:
class Person(models.Model):
class Meta:
verbose_name_plural = "people"
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)

Use of django.conf.settings

Modules should not in general use settings stored in django.conf.settingsat the top level (i.e. evaluated when the module is imported). The explanation for this is as follows:

Manual configuration of settings (i.e. not relying on theDJANGO_SETTINGS_MODULE environment variable) is allowed and possible as follows:

from django.conf import settings

settings.configure({}, SOME_SETTING="foo")

However, if any setting is accessed before the settings.configure line, this will not work. (Internally, settings is a LazyObject which configures itself automatically when the settings are accessed if it has not already been configured).

So, if there is a module containing some code as follows:

from django.conf import settings from django.urls import get_callable

default_foo_view = get_callable(settings.FOO_VIEW)

…then importing this module will cause the settings object to be configured. That means that the ability for third parties to import the module at the top level is incompatible with the ability to configure the settings object manually, or makes it very difficult in some circumstances.

Instead of the above code, a level of laziness or indirection must be used, such as django.utils.functional.LazyObject,django.utils.functional.lazy() or lambda.

Miscellaneous

JavaScript style

For details about the JavaScript code style used by Django, seeJavaScript code.