• 3.2
  • 5.0
  • 6.1
  • Версия документации: 3.1

Стиль кодинга

Пожалуйста, следуйте этим стандартам кодирования при написании кода для Django.

Стиль Python

  • Please conform to the indentation style dictated in the .editorconfig file. We recommend using a text editor with EditorConfig support to avoid indentation and whitespace issues. The Python files use 4 spaces for indentation and the HTML files use 2 spaces.

  • Если не указано иное, следуйте PEP 8.

    Use flake8 to check for problems in this area. Note that our setup.cfg file contains some excluded files (deprecated modules we don’t care about cleaning up and some third-party code that Django vendors) as well as some excluded errors that we don’t consider as gross violations. Remember that PEP 8 is only a guide, so respect the style of the surrounding code as a primary goal.

    An exception to PEP 8 is our rules on line lengths. Don’t limit lines of code to 79 characters if it means the code looks significantly uglier or is harder to read. We allow up to 119 characters as this is the width of GitHub code review; anything longer requires horizontal scrolling which makes review more difficult. This check is included when you run flake8. Documentation, comments, and docstrings should be wrapped at 79 characters, even though PEP 8 suggests 72.

  • Use four spaces for indentation.

  • Use four space hanging indentation rather than vertical alignment:

    raise AttributeError(
        'Here is a multiline error message '
        'shortened for clarity.'
    )
    

    Instead of:

    raise AttributeError('Here is a multiline error message '
                         'shortened for clarity.')
    

    This makes better use of space and avoids having to realign strings if the length of the first line changes.

  • Use single quotes for strings, or a double quote if the string contains a single quote. Don’t waste time doing unrelated refactoring of existing code to conform to this style.

  • Для интерполяции строковых переменных можно использовать %, f-строки или str.format() по мере необходимости, с целью максимизации читаемости кода.

    Окончательное решение о читаемости остается на усмотрение мерджера. f-строки должны использовать только простой доступ к переменным и свойствам, с предварительным локальным назначением переменных для более сложных случаев:

    # 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-строки не следует использовать для строк, которые могут потребовать перевода, включая сообщения об ошибках и журналирование. format() более многословен, поэтому предпочтительны другие методы форматирования.

    Не тратьте время на рефакторинг существующего кода для корректировки метода форматирования.

  • Избегайте использования «we» в комментариях, например «Loop over» вместо «We loop».

  • Используйте подчеркивания, а не camelCase, для имен переменных, функций и методов (т. е. poll.get_unique_voters(), а не poll.getUniqueVoters()).

  • Используйте InitialCaps для имен классов.

  • В строках документации следуйте стилю существующих строк документации и PEP 257.

  • В тестах используйте assertRaisesMessage() и assertWarnsMessage() вместо assertRaises() и assertWarns() чтобы можно было проверить сообщение об исключении или предупреждении. Используйте assertRaisesRegex() и assertWarnsRegex() только если вам нужно сопоставление с регулярным выражением.

    Используйте assertIs(…, True/False) для проверки логических значений, а не assertTrue() и assertFalse(), чтобы можно было проверить фактическое логическое значение, а не истинность выражения.

  • В строках документации тестов укажите ожидаемое поведение, которое демонстрирует каждый тест. Не включайте преамбулы, такие как «Tests that» или «Гарантирует, что».

    Зарезервируйте ссылки на тикеты для неясных проблем, когда тикет имеет дополнительные подробности, которые нельзя легко описать в строках документации или комментариях. Включите номер тикета в конец предложения, например:

    def test_foo():
        """
        A test docstring looks like this (#123456).
        """
        ...
    

Импорты

  • Use isort to automate import sorting using the guidelines below.

    Быстрый старт:

    $ python -m pip install isort >= 5.1.0
    $ isort -rc .
    
    ...\> py -m pip install isort >= 5.1.0
    ...\> isort -rc .
    

    Это запускает isort рекурсивно из вашего текущего каталога, изменяя любые файлы, которые не соответствуют правилам. Если вам нужно, чтобы импорт был выполнен не по порядку (например, чтобы избежать циклического импорта), используйте такой комментарий:

    import module  # isort:skip
    
  • Поместите импорты в эти группы: future, стандартная библиотека, сторонние библиотеки, другие компоненты Django, локальный компонент Django, try/exceptions. Отсортируйте строки в каждой группе в алфавитном порядке по полному имени модуля. Поместите все import module операторы перед from module import objects в каждом разделе. Используйте абсолютный импорт для других компонентов Django и относительный импорт для локальных компонентов

  • В каждой строке расположите элементы в алфавитном порядке, сгруппировав элементы с заглавными буквами перед элементами со строчными буквами.

  • Разрывайте длинные строки с помощью скобок и делайте отступы строк продолжения на 4 пробела. Включайте завершающую запятую после последнего импорта и помещайте закрывающую скобку на отдельную строку.

    Используйте одну пустую строку между последним импортом и любым кодом уровня модуля, и используйте две пустые строки над первой функцией или классом.

    Например (комментарии носят исключительно пояснительный характер):

    django/contrib/admin/example.py
    # 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:
        # ...
    
  • Use convenience imports whenever available. For example, do this:

    from django.views import View
    

    вместо:

    from django.views.generic.base import View
    

Стиль шаблонов

  • In Django template code, put one (and only one) space between the curly brackets and the tag contents.

    Делайте это:

    {{ foo }}
    

    Не делайте этого:

    {{foo}}
    

Стиль представлений

  • В представлениях Django первый параметр в функции представления должен называться request.

    Делайте это:

    def my_view(request, foo):
        # ...
    

    Не делайте этого:

    def my_view(req, foo):
        # ...
    

Стиль моделей

  • Имена полей должны быть написаны строчными буквами, с использованием подчеркиваний вместо camelCase.

    Делайте это:

    class Person(models.Model):
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
    

    Не делайте этого:

    class Person(models.Model):
        FirstName = models.CharField(max_length=20)
        Last_Name = models.CharField(max_length=40)
    
  • class Meta должен располагаться после определения полей, с одной пустой строкой, разделяющей поля и определение класса.

    Делайте это:

    class Person(models.Model):
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
    
        class Meta:
            verbose_name_plural = 'people'
    

    Не делайте этого:

    class Person(models.Model):
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
        class Meta:
            verbose_name_plural = 'people'
    

    Don’t do this, either:

    class Person(models.Model):
        class Meta:
            verbose_name_plural = 'people'
    
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
    
  • Порядок внутренних классов модели и стандартных методов должен быть следующим(отметим, что не все они обязательны):

    • Все поля базы данных

    • Пользовательские атрибуты менеджера

    • class Meta

    • def __str__()

    • def save()

    • def get_absolute_url()

    • Любые пользовательские методы

  • If choices is defined for a given model field, define each choice as a list of tuples, with an all-uppercase name as a class attribute on the model. Example:

    class MyModel(models.Model):
        DIRECTION_UP = 'U'
        DIRECTION_DOWN = 'D'
        DIRECTION_CHOICES = [
            (DIRECTION_UP, 'Up'),
            (DIRECTION_DOWN, 'Down'),
        ]
    

«Использование django.conf.settings

В общем случае, модули не должны использовать настройки, хранящиеся в django.conf.settings на верхнем уровне (т. е. оцениваются при импорте модуля). Объяснение этому следующее:

Ручная настройка параметров (т. е. без использования переменной окружения DJANGO_SETTINGS_MODULE) разрешена и возможна:

from django.conf import settings

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

Однако, если доступ к какой-либо настройке осуществляется до строки settings.configure, это не сработает. (Внутренне settings - это LazyObject, который автоматически настраивается при доступе к настройкам, если он еще не был настроен).

Если есть модуль, содержащий следующий код:

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

default_foo_view = get_callable(settings.FOO_VIEW)

…тогда импорт этого модуля приведет к настройке объекта настроек. Это означает, что возможность для третьих лиц импортировать модуль на верхнем уровне несовместима с возможностью настройки объекта настроек вручную или делает это очень сложным в некоторых обстоятельствах.

Вместо этого кода необходимо использовать уровень laziness, например, django.utils.functional.LazyObject, django.utils.functional.lazy() или lambda.

Разнообразный

  • Отметить все строки для интернационализации; подробности см. в i18n-документации.

  • Remove import statements that are no longer used when you change code. flake8 will identify these imports for you. If an unused import needs to remain for backwards-compatibility, mark the end of with # NOQA to silence the flake8 warning.

  • Систематически удаляйте все конечные пробелы из вашего кода, так как они добавляют ненужные байты, визуально загромождают патчи и могут также иногда вызывать ненужные конфликты слияния. Некоторые IDE можно настроить на автоматическое их удаление, а большинство инструментов VCS можно настроить на их выделение в результатах сравнения diff.

  • Пожалуйста, не указывайте свое имя в коде, который вы вносите. Наша политика заключается в том, чтобы сохранять имена участников в файле AUTHORS, распространяемом с Django, а не разбросанными по всей кодовой базе. Не стесняйтесь включать изменение в файл AUTHORS в вашем патче, если вы вносите более одного тривиального изменения.

Стиль Javascript

Подробнее о стиле кода JavaScript, используемом Django, см. JavaScript.

Back to Top