Files
SecondBrain/90 Library/Programming/Python/Django: Модели и ORM.md
T
2026-05-31 10:03:46 +03:00

7.0 KiB

status, type, tags, created, updated, title, source
status type tags created updated title source
processing concept
django
backend
orm
database
migrations
2026-05-30 2026-05-31 Django: Модели и ORM
lec1-django_start_models-1.pdf
lec4-django_lec_queries.pdf
p1-django-1.pdf

Django Модели и ORM

Django ORM (Object-Relational Mapping) — технология связи объектно-ориентированного кода и реляционной БД. Реализует паттерн Active Record.

Структура проекта

  • manage.py: Утилита командной строки.
  • settings.py: Конфигурация проекта (БД, INSTALLED_APPS).
  • urls.py: Описание маршрутов.
  • models.py: Определение таблиц БД.

Определение моделей

from django.db import models

class Person(models.Model):
    first_name = models.CharField("Имя", max_length=30)
    age = models.IntegerField(default=18)
    bio = models.TextField(blank=True)
    
    class Meta:
        verbose_name = "Человек"
        ordering = ["-first_name"]

Типы полей

  • AutoField — автоинкрементный числовой первичный ключ.
  • CharField(max_length=N) — короткая строка фиксированной максимальной длины.
  • TextField — длинный текст без обязательного ограничения длины.
  • IntegerField — целое число.
  • DecimalField(max_digits, decimal_places) — точное десятичное число, удобно для денег и измерений.
  • BooleanField — логическое значение True/False.
  • DateField — дата без времени.
  • DateTimeField — дата и время.
  • EmailField — строка с валидацией email-адреса.
  • FileField — путь к загруженному файлу.
  • ImageField — файл изображения с дополнительной проверкой формата.

Отношения

  • ForeignKey(Target, on_delete=...) — связь «один ко многим»: у одной записи Target может быть много связанных записей текущей модели.
  • OneToOneField(Target, on_delete=...) — связь «один к одному»: каждой записи соответствует максимум одна связанная запись.
  • ManyToManyField(Target) — связь «многие ко многим»: записи обеих моделей могут ссылаться на несколько записей другой модели.

on_delete задаёт, что делать с текущей записью, если удаляется связанная запись Target:

  • CASCADE — удалить текущую запись вместе со связанной.
  • PROTECT — запретить удаление связанной записи, пока на неё есть ссылки.
  • SET_NULL — записать NULL в поле связи; требует null=True.
  • SET_DEFAULT — записать значение по умолчанию; требует default.
  • DO_NOTHING — ничего не делать на уровне Django, ответственность остаётся на БД и разработчике.

Миграции

Инструмент для синхронизации моделей с БД.

  • python manage.py makemigrations — создать файлы миграций.
  • python manage.py migrate — применить изменения в БД.
  • python manage.py showmigrations — список статусов миграций.

Работа с QuerySet (Запросы)

Django QuerySet ленивы (вычисляются только при обращении) и поддерживают цепочки методов.

Базовые CRUD операции

  • Create: obj = Person.objects.create(name="Ivan") или obj.save().
  • Read:
    • Person.objects.all() (все),
    • Person.objects.get(id=1) (один),
    • Person.objects.filter(age__gt=20) (фильтрация).
  • Update: Person.objects.filter(id=1).update(age=25).
  • Delete: obj.delete() или QuerySet.delete().

Поиск по полям (Field Lookups)

  • exact, iexact (регистронезависимо).
  • gt (>), gte (>=), lt (<), lte (<=).
  • contains, icontains.
  • in (список), range (диапазон).
  • isnull=True.

Оптимизация запросов

  • select_related('field') — заранее подтягивает связанную запись через JOIN. Подходит для ForeignKey и OneToOneField, когда у объекта есть одна связанная запись.
  • prefetch_related('field') — делает отдельный запрос за связанными объектами и собирает их в Python. Подходит для ManyToManyField и обратных связей, где связанных записей может быть много.
  • Проблема N+1 — ситуация, когда Django делает один запрос за списком объектов, а потом ещё по одному запросу на каждый объект в цикле.

Пример: если вывести 100 книг и для каждой обратиться к book.author, без оптимизации может получиться 101 запрос. С select_related('author') авторы будут загружены сразу.

Агрегация и аннотация

  • aggregate(Avg('rating')) — считает одно итоговое значение по всей выборке: среднее, сумму, минимум, максимум, количество. Возвращает словарь, а не QuerySet.
  • annotate(total=Count('entries')) — добавляет вычисляемое поле к каждому объекту в выборке.

Пример: Book.objects.aggregate(Avg('rating')) вернёт средний рейтинг всех книг. Author.objects.annotate(total=Count('books')) добавит каждому автору поле total с количеством его книг.

Логические условия

  • Q-объекты нужны для сложных условий в filter(): OR (|), AND (&), NOT (~).
  • F-выражения позволяют сравнивать и изменять поля прямо на стороне БД, не загружая значение в Python.

Пример Q: найти книги, где рейтинг выше 4 или название содержит Django. Пример F: увеличить счётчик просмотров на 1 прямо в БД: views = F('views') + 1.