1. Менеджер моделей
В Django ORM менеджер моделей — это интерфейс для выполнения запросов к базе данных для конкретной модели. Менеджеры отвечают за создание, фильтрацию, обновление и удаление записей.
Каждая модель Django имеет встроенный менеджер
objects. Он предоставляет доступ ко всем методам QuerySet API.
Основные группы методов objects
| Группа | Методы |
|---|---|
| Создание | create(), bulk_create() |
| Чтение | all(), filter(), exclude(), get(), count(), exists() |
| Обновление | update() |
| Удаление | delete() |
2. Django Shell
Django Shell — интерактивная Python-оболочка, настроенная на ваш проект. Позволяет выполнять ORM-запросы прямо из терминала без написания view или скриптов.
Как запустить
# Запуск Django Shell
python manage.py shell
Работа в Django Shell
# 1. Импорт моделей
from store.models import Book # конкретная модель
# или
from store.models import * # все модели приложения
# 2. Выполнение ORM-запросов
all_books = Book.objects.all()
print(all_books)
Используйте
python manage.py shell_plus (пакет django-extensions) — он автоматически импортирует все модели.
3. QuerySet
QuerySet — объект, представляющий набор данных из базы данных. Основные свойства:
- Ленивость (lazy): SQL-запрос выполняется только когда данные реально нужны (итерация, приведение к списку, срез)
- Цепочки (chaining): методы можно объединять —
.filter().order_by().values() - Кешируемость: после первого выполнения результат кешируется внутри QuerySet
# QuerySet ленивый — запрос ещё не отправлен
qs = Book.objects.filter(author="Orwell")
# Запрос выполняется здесь — при итерации
for book in qs:
print(book.title)
4. Создание записей
Метод create()
Создаёт и сохраняет новую запись в БД за один шаг:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
published_date = models.DateField()
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
# Создание новой книги
new_book = Book.objects.create(
title="The Great Gatsby",
author="F. Scott Fitzgerald",
published_date="1925-04-10",
price=15
)
# Объект автоматически сохранён в БД
print(new_book.id) # ID присвоен базой данных
Метод save()
Даёт возможность изменить объект до сохранения:
# Создание экземпляра без сохранения
new_book = Book(
title="1984",
author="George Orwell",
published_date="1949-06-08",
price=20
)
# Изменение до сохранения
new_book.title = "Nineteen Eighty-Four"
# Явное сохранение в БД
new_book.save()
print(new_book.id)
create() | save() | |
|---|---|---|
| Шагов | 1 | 2+ |
| Когда использовать | Простое создание | Нужна обработка перед сохранением |
| SQL | INSERT | INSERT или UPDATE |
5. Чтение записей
Метод all()
Возвращает QuerySet со всеми записями таблицы:
all_books = Book.objects.all()
for book in all_books:
print(book.title)
Метод first() и last()
Возвращают первую/последнюю запись или None если QuerySet пуст:
first_book = Book.objects.all().first()
if first_book:
print(f"Первая книга: {first_book.title}")
last_book = Book.objects.all().last()
if last_book:
print(f"Последняя книга: {last_book.title}")
Метод count()
Возвращает количество записей (выполняет SELECT COUNT(*)):
book_count = Book.objects.all().count()
print(f"Количество книг: {book_count}")
Метод exists()
Возвращает True/False — есть ли хотя бы одна запись. Эффективнее, чем count() > 0:
has_books = Book.objects.all().exists()
print(f"Книги существуют: {has_books}")
Метод values()
Возвращает QuerySet словарей, а не объектов модели. Полезен для получения только нужных полей:
books_values = Book.objects.all().values('title', 'author')
for book in books_values:
print(f"Название: {book['title']}, Автор: {book['author']}")
6. Метод get()
Используется для получения ровно одной записи по заданным критериям:
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
# Поиск по одному полю
try:
book = Book.objects.get(title="The Great Gatsby")
print(f"Книга найдена: {book.title}")
except ObjectDoesNotExist:
print("Книга не найдена.")
except MultipleObjectsReturned:
print("Найдено несколько книг с одинаковым названием.")
# Поиск по нескольким полям
try:
book = Book.objects.get(title="The Great Gatsby", author="F. Scott Fitzgerald")
print(f"Книга найдена: {book.title}")
except ObjectDoesNotExist:
print("Книга не найдена.")
except MultipleObjectsReturned:
print("Найдено несколько книг.")
get()Model.DoesNotExist(илиObjectDoesNotExist) — запись не найденаMultipleObjectsReturned— найдено более одной записи
get() только для поиска по уникальным полям (например, id, email).
7. Фильтры: filter() и exclude()
Основные методы выборки по условию. filter() выбирает подходящие, exclude() — исключает подходящие:
# filter() — выбрать записи, соответствующие условию
bestsellers = Book.objects.filter(is_bestseller=True)
# exclude() — исключить записи, соответствующие условию
non_bestsellers = Book.objects.exclude(is_bestseller=True)
# Можно цеплять
recent_bestsellers = Book.objects.filter(
is_bestseller=True
).exclude(
published_date__lt="2000-01-01"
)
8. Lookups — условия фильтрации
Lookups — механизм построения условий через синтаксис поле__условие=значение. Используются в filter(), exclude(), get().
__. Например: author__icontains='john' → «поле author содержит 'john' без учёта регистра».
Точное совпадение
# exact — точное совпадение (регистрозависимо)
books = Book.objects.filter(title__exact="The Great Gatsby")
# iexact — точное совпадение без учёта регистра
books = Book.objects.filter(title__iexact="the great gatsby")
Поиск подстроки
# contains — содержит подстроку (регистрозависимо)
books = Book.objects.filter(title__contains="Gatsby")
# icontains — содержит подстроку (без учёта регистра)
books = Book.objects.filter(title__icontains="gatsby")
Начало и конец строки
# startswith / istartswith
books = Book.objects.filter(title__startswith="The")
books = Book.objects.filter(title__istartswith="the")
# endswith / iendswith
books = Book.objects.filter(title__endswith="Gatsby")
books = Book.objects.filter(title__iendswith="gatsby")
Список значений (in)
# in — значение входит в список
books = Book.objects.filter(id__in=[1, 2, 3])
Сравнение чисел и дат
# gt — больше; gte — больше или равно
# lt — меньше; lte — меньше или равно
books = Book.objects.filter(published_date__gt="2000-01-01")
books = Book.objects.filter(published_date__gte="2000-01-01")
books = Book.objects.filter(published_date__lt="2000-01-01")
books = Book.objects.filter(published_date__lte="2000-01-01")
Проверка на NULL
# isnull — поле равно NULL
books = Book.objects.filter(published_date__isnull=True)
books = Book.objects.filter(published_date__isnull=False)
Диапазон значений
# range — значение в диапазоне (включая границы)
books = Book.objects.filter(
published_date__range=["2022-01-01", "2023-01-01"]
)
9. Класс Q — сложные логические условия
Класс Q позволяет строить запросы с логическими операторами AND, OR, NOT — то, что невозможно выразить через обычный filter().
from django.db.models import Q
# AND (&) — оба условия должны быть истинны
books = Book.objects.filter(
Q(is_bestseller=True) & Q(published_date__gt="2000-01-01")
)
# OR (|) — хотя бы одно условие истинно
books = Book.objects.filter(
Q(is_bestseller=True) | Q(published_date__gt="2000-01-01")
)
# NOT (~) — условие ложно
books = Book.objects.filter(~Q(is_bestseller=True))
# Комбинация: (бестселлер ИЛИ после 2000) И НЕ Оруэлл
books = Book.objects.filter(
(Q(is_bestseller=True) | Q(published_date__gt="2000-01-01"))
& ~Q(author="George Orwell")
)
Простые AND-условия можно писать через
filter(a=1, b=2) — без Q. Класс Q нужен, когда требуется OR или NOT.
aget(), acreate(), acount(), aaggregate() и асинхронная итерация (async for obj in qs). Отдельного afilter() нет: сам filter() ленивый и остаётся синхронным (он не обращается к БД до материализации). Для синхронного кода всё описанное выше актуально. См. официальную документацию.