Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Django ORM — Object-Relational Mapping
Django ORM — это слой абстракции, который позволяет работать с базой данных через Python классы вместо писания SQL запросов вручную.
Основная идея
# БЕЗ ORM — сырой SQL
import psycopg2
conn = psycopg2.connect("dbname=mydb")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE age > %s", (18,))
rows = cursor.fetchall()
# С Django ORM — Python код
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
users = User.objects.filter(age__gt=18) # Намного удобнее
Определение моделей
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField(unique=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created_at"]
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=300)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
published = models.DateField()
views = models.IntegerField(default=0)
Когда создаёшь модель — Django автоматически создаёт таблицу (через миграции).
Основные операции (CRUD)
# CREATE — создание
author = Author.objects.create(name="Лев Толстой", email="tolstoy@example.com")
# READ — чтение
all_authors = Author.objects.all()
one_author = Author.objects.get(id=1) # Или исключение DoesNotExist
filtered = Author.objects.filter(name__icontains="Толстой") # Поиск
# UPDATE — обновление
author.name = "Лев Толстой (обновлено)"
author.save()
# DELETE — удаление
author.delete()
Связи между моделями
# ForeignKey — один ко многим
class Comment(models.Model):
text = models.TextField()
book = models.ForeignKey(Book, on_delete=models.CASCADE)
# ManyToMany — многие ко многим
class Tag(models.Model):
name = models.CharField(max_length=50)
books = models.ManyToManyField(Book, related_name="tags")
# Связь в обратном направлении
book = Book.objects.get(id=1)
comments = book.comment_set.all() # Все комментарии к книге
Фильтрация и запросы
# Простой фильтр
books = Book.objects.filter(author__name="Толстой")
# Сложный фильтр (Q объекты)
from django.db.models import Q
books = Book.objects.filter(
Q(author__name="Толстой") | Q(author__name="Достоевский")
)
# Исключение
books = Book.objects.exclude(views__lt=100)
# Сортировка
books = Book.objects.all().order_by("-published") # По дате, убывающий
# Ограничение результатов
top_10 = Book.objects.all()[:10]
Агрегация и статистика
from django.db.models import Count, Sum, Avg
# Количество книг по авторам
author_stats = Author.objects.annotate(book_count=Count("book"))
# Средний рейтинг
avg_rating = Book.objects.aggregate(Avg("rating"))
Миграции
# Создание миграции (описание изменений моделей)
python manage.py makemigrations
# Применение миграций к БД
python manage.py migrate
Плюсы и минусы
Плюсы:
- Безопасность от SQL-инъекций
- Код работает с разными БД (PostgreSQL, MySQL, SQLite)
- Меньше кода, больше читаемости
- Встроенная валидация
Минусы:
- Может быть медленнее чем сырой SQL для сложных запросов
- Сложно отладить если ORM делает не то что ты хочешь
- N+1 проблема (много запросов вместо одного)
Решение N+1 проблемы
# ❌ Плохо — 11 запросов (1 для авторов + 10 для каждой книги)
for book in Book.objects.all()[:10]:
print(book.author.name)
# ✅ Хорошо — 2 запроса
books = Book.objects.select_related("author").all()[:10]
for book in books:
print(book.author.name) # Данные уже загружены
Дjango ORM — это мощный инструмент, который упрощает работу с БД, но нужно понимать как он работает под капотом.