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.

Усовершенствованное отображение форм с помощью Django Crispy Forms

В этом уроке мы собираемся изучить некоторые функции Django Crispy Forms для обработки расширенных/пользовательских форм с использованием Bootstrap 4.

Запрос по сумме из связанной модели

Понадобилось тут найти несоответствие суммы платежа Payment с суммой связанных ним элементов PaymentItem. Решается это простой аннотацией.

Стала доступна версия Django 3.0 alpha 1

Стала доступна версия Django 3.0 alpha 1. Она представляет собой первый этап цикла выпуска 3.0 и дает вам возможность опробовать изменения, появившиеся в Django 3.0.

Исправления ошибок Django 2.2.5, 2.1.12 и 1.11.24

Сегодня команда разработчиков Django выпустила версии с исправлениями 2.2.5, 2.1.12 и 1.11.24. Пакет релиза и контрольные суммы доступны на странице загрузок, а также из индекса пакетов Python. Идентификатор ключа PGP, использованный в этом выпуске: Mariusz Felisiak: 2EF56372BA48CD1B.

Создание большой XML-карты сайта для Django

Предположим, что у вас так много страниц (тысячи), что вы не можете просто создать один файл /sitemap.xml, в котором перечислены все URL-адреса (он же <loc>). Поэтому вам нужно создать /sitemaps.xml, который указывает на другие файлы карты сайта. А если адресов в каждом тысячи, то нужно сжать эти файлы.

Добавление хранилища Amazon S3 в проект Джанго

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

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

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

Создание погодного приложения на Python

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

Django 2.2.1 - исправления ошибок

Сегодня выпустили версию 2.2.1 с исправлениями ошибок.

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

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