← Назад к вопросам

Что такое Django ORM?

1.3 Junior🔥 221 комментариев
#Django#Базы данных (SQL)

Комментарии (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 — это мощный инструмент, который упрощает работу с БД, но нужно понимать как он работает под капотом.

Что такое Django ORM? | PrepBro