Everything you wanted to know
about the Django framework

Проектирование моделей в Django

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

Ниже можно ознакомиться с рекомендациями по оформлению кода на Django.

Названия моделей

Так как модель — это класс, то всегда используем соглашение CapWords, т. е. каждое слово в имени модели начинаем с заглавной буквы, без подчеркиваний. Например User, Permission, ContentType и т. д.

Для атрибутов моделей используем snake_case, т.е. все слова с маленькой буквы с разделением подчеркиванием. Например first_name, last_name.

Пример:

from django.db import models

class Company(models.Model):
    name = models.CharField(max_length=30)
    vat_identification_number = models.CharField(max_length=20)

Также для имени модели всегда используйте единственное число: Company вместо Companies. Определение модели — это представление единственного объекта (в данном примере компания), а не множества.

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

Последовательность размещения внутри класса модели

Рекомендации Django по последовательности размещения внутренних классов, методов и атрибутов следующие:

  • если для поля модели определены варианты (choices), определите каждый вариант выбора как кортеж кортежей, используя заглавные буквы;
  • поля данных модели;
  • атрибуты пользовательского менеджера;
  • class Meta;
  • def __str__();
  • def save();
  • def get_absolute_url();
  • остальные методы вашего класса.

Пример:

from django.db import models
from django.urls import reverse

class Company(models.Model):
    # CHOICES
    PUBLIC_LIMITED_COMPANY = 'PLC'
    PRIVATE_COMPANY_LIMITED = 'LTD'
    LIMITED_LIABILITY_PARTNERSHIP = 'LLP'
    COMPANY_TYPE_CHOICES = (
        (PUBLIC_LIMITED_COMPANY, 'Public limited company'),
        (PRIVATE_COMPANY_LIMITED, 'Private company limited by shares'),
        (LIMITED_LIABILITY_PARTNERSHIP, 'Limited liability partnership'),
    )

    # DATABASE FIELDS
    name = models.CharField('name', max_length=30)
    vat_identification_number = models.CharField('VAT', max_length=20)
    company_type = models.CharField('type', max_length=3, choices=COMPANY_TYPE_CHOICES)

    # MANAGERS
    objects = models.Manager()
    limited_companies = LimitedCompanyManager()

    # META CLASS
    class Meta:
        verbose_name = 'company'
        verbose_name_plural = 'companies'

    # TO STRING METHOD
    def __str__(self):
        return self.name

    # SAVE METHOD
    def save(self, *args, **kwargs):
        do_something()
        super().save(*args, **kwargs)  # Call the "real" save() method.
        do_something_else()

    # ABSOLUTE URL METHOD
    def get_absolute_url(self):
        return reverse('company_details', kwargs={'pk': self.id})

    # OTHER METHODS
    def process_invoices(self):
        do_something()

Обратные отношения

related_name

Это атрибут используется в поле ForeignKey. Он позволяет указать нормальное и удобное имя для обратного отношения (reverse relationship).

Например:

class Company:
    name = models.CharField(max_length=30)

class Employee:
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='employees')

Этот код означает, что у объекта модели Company появится атрибут employees, который возвращает QuerySet со всеми объектами работников указанной компании.

google = Company.objects.get(name='Google')
google.employees.all()

Пустые и нулевые поля

Разница между пустыми и нулевыми полями уже обсуждалась, но повторю:

  • null: связан с базой данных, определяет, будет ли данный столбец базы данных принимать нулевые значения или нет.
  • blank: связан с валидацией Django, используется во время проверки формы при вызове form.is_valid ().

Не используйте значение null=True для текстовых полей, которые являются необязательными. В противном случае вы получите два возможных значения для «нет данных»: «Нет» и пустая строка. Наличие двух возможных значений для «нет данных» является избыточным. Соглашение Django должно использовать пустую строку, а не NULL.

# The default values of `null` and `blank` are `False`.
# значение по умолчанию для null и blank - False
class Person(models.Model):
    name = models.CharField(max_length=255)  # обязательное
    bio = models.TextField(max_length=500, blank=True) # необязательное (не используйте null=True для текстовых полей)
    birth_date = models.DateField(null=True, blank=True) # необязательное (здесь нужно использовать оба атрибута null и blank)

Заключение

Определение модели — важная часть вашего приложения. Детальное рассмотрение рекомендаций вы можете посмотреть в документации Django’s Coding Style.

Поделитесь с другими:

Представления-классы
(Class-Based Views)

Детальное описание и структура классов Django.

Пользовательская модель User

Каждый новый проект Django должен использовать пользовательскую модель User. Официальная документация Django гласит, что это «настоятельно рекомендуется», но я сделаю еще один шаг и без колебаний скажу: вы просто с ума сошли, если не использовали пользовательскую модель раньше.

Исправление ошибок, Django 2.1.8

Выпущена новая версия Django 2.1.8, в которой исправлена ошибка в админке, допущенная в версии 2.1.7: запрещено редактировать inline-элементы для ManyToManyField, если у пользователя есть только разрешение на просмотр.

Аутентификация в Django: полный пример входа, выхода и смены пароля

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

Django 2.2 предварительный выпуск 1

Выпущен релиз-кандидат 1 версии Django 2.2, в котором вы можете предварительно протестировать некоторые новые возможности перед выпуском Django 2.2.

Поиск узких мест производительности проекта на Django

При оптимизации производительности веб-приложения распространенная ошибка — начинать с оптимизации самой медленной страницы (или API). Помимо учета времени отклика, мы также должны учитывать трафик, который он получает, чтобы определить порядок оптимизации. В этой статье мы расскажем о веб-приложении Django, найдем узкие места с высокой эффективностью, а затем приступим к их оптимизации для повышения производительности.

Просмотр SQL запросов Django

Django ORM позволяет легко взаимодействовать с базой данных. Чтобы понять, что происходит за кулисами или увидеть производительность SQL, мы можем записать все запросы SQL, которые выполняются. В этой статье мы увидим различные способы достижения этого.

Как подключить виджет выбора даты в Django

Из этого руководства вы узнаете как легко подключить виджет выбора даты в своем проекте Django. Мы узнаем, как установить его вручную, потом как настроить пользовательский виджет и, наконец, как использовать стороннее приложение Django с поддержкой средств выбора даты и времени.

Исправление ошибок, Django 2.0.13

Сегодня был осуществлен новый выпуск исправлений Django 2.0.13. Исправлен сбой в django.utils.numberformat.format_number(), когда число имеет более 200 цифр (#30177).

Новый формат middleware в Django 2

MIddleware (промежуточный слой) используются для модификации объекта приходящего запроса в представление (view) или для модификации объекта ответа, возвращаемого из представления. Они позволяют нам изменять запросы/ответы глобально.

Массовое обновление записей в Django используя аннотации и подзапросы

Как массово обновлять записи в Django с помощью аннотаций и подзапросов.