Проектирование моделей в 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.
Вернуться на верх