88 lines
3.8 KiB
Markdown
88 lines
3.8 KiB
Markdown
---
|
|
status: seed
|
|
type: concept
|
|
tags: [django, backend, orm, database, migrations]
|
|
created: 2026-05-30
|
|
updated: 2026-05-30
|
|
title: Django: Модели и ORM
|
|
source: ["[[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`: Определение таблиц БД.
|
|
|
|
## Определение моделей
|
|
```python
|
|
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`, `DateField`, `DateTimeField`.
|
|
- `EmailField`, `FileField`, `ImageField`.
|
|
|
|
### Отношения
|
|
- `ForeignKey(Target, on_delete=models.CASCADE)` — Один ко многим.
|
|
- `OneToOneField(Target, on_delete=models.CASCADE)` — Один к одному.
|
|
- `ManyToManyField(Target)` — Многие ко многим.
|
|
- **on_delete:** `CASCADE`, `PROTECT`, `SET_NULL`, `SET_DEFAULT`, `DO_NOTHING`.
|
|
|
|
---
|
|
|
|
## Миграции
|
|
Инструмент для синхронизации моделей с БД.
|
|
- `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')`: INNER JOIN для ForeignKey и OneToOne.
|
|
- `prefetch_related('field')`: 2-й запрос для ManyToMany и обратных связей.
|
|
- **Проблема N+1:** Возникает при обращении к связанным полям в цикле без предварительной подгрузки.
|
|
|
|
### Агрегация и аннотация
|
|
- `aggregate(Avg('rating'))`: терминальный метод, возвращает словарь.
|
|
- `annotate(total=Count('entries'))`: добавляет вычисляемое поле к каждому объекту в выборке.
|
|
|
|
### Логические условия
|
|
- `Q-объекты`: Позволяют использовать `OR` (`|`), `AND` (`&`), `NOT` (`~`).
|
|
- `F-выражения`: Ссылки на поля в БД (атомарные операции без Race Condition).
|