Класс Manager
Класс Manager является интерфейсом между моделью и базой данных. Он предоставляет методы для создания, чтения, обновления и удаления записей. По умолчанию каждая модель получает менеджер с именем objects, который содержит базовый набор методов для работы с QuerySet. Вы можете создавать собственные менеджеры для добавления специфической логики запросов или изменения стандартного поведения.
Стандартный менеджер
Рассмотрим использование стандартного менеджера objects для выполнения базовых операций с моделью:
from myapp.models import Article
# Создание записи
article = Article.objects.create(
title="Django Manager",
status="draft"
)
# Получение всех записей
all_articles = Article.objects.all()
print(all_articles)
Результат выполнения кода:
[<Article: Django Manager>]
Кастомный менеджер
Создадим собственный менеджер для добавления часто используемых фильтров. Менеджер наследуется от Manager и добавляет методы, возвращающие QuerySet с определенными условиями:
from django.db import models
class ArticleManager(models.Manager):
def published(self):
return self.filter(status="published")
def recent(self, days=7):
from datetime import timedelta
from django.utils import timezone
cutoff_date = timezone.now() - timedelta(days=days)
return self.filter(created_at__gte=cutoff_date)
class Article(models.Model):
title = models.CharField(max_length=200)
status = models.CharField(max_length=20)
created_at = models.DateTimeField(auto_now_add=True)
objects = ArticleManager()
Теперь можно использовать эти методы для получения отфильтрованных записей:
from myapp.models import Article
# Получаем только опубликованные статьи
published = Article.objects.published()
print(published)
# Получаем статьи за последние 3 дня
recent_articles = Article.objects.recent(days=3)
print(recent_articles)
Результат выполнения кода:
[<Article: Первая статья>, <Article: Вторая статья>]
[<Article: Вторая статья>]
Переопределение базового QuerySet
Можно переопределить метод get_queryset для изменения набора записей по умолчанию. Это полезно для фильтрации мягко удаленных записей или применения постоянных условий:
from django.db import models
class ActiveManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
class Product(models.Model):
name = models.CharField(max_length=100)
is_active = models.BooleanField(default=True)
price = models.IntegerField()
# Менеджер для активных товаров
active_objects = ActiveManager()
# Стандартный менеджер для всех товаров
objects = models.Manager()
При использовании active_objects автоматически применяется фильтрация по активным записям:
from myapp.models import Product
# Получаем только активные товары
active_products = Product.active_objects.all()
print(active_products)
# Получаем все товары, включая неактивные
all_products = Product.objects.all()
print(all_products)
Результат выполнения кода:
[<Product: Ноутбук>, <Product: Мышь>]
[<Product: Ноутбук>, <Product: Мышь>, <Product: Клавиатура>]
Комбинирование методов менеджера
Методы менеджера можно комбинировать в цепочки для построения сложных запросов. Каждый метод возвращает QuerySet, что позволяет применять дополнительные фильтры:
from myapp.models import Article
# Комбинируем методы опубликованных и недавних статей
recent_published = Article.objects.published().recent(days=7)
print(recent_published)
# Добавляем дополнительную фильтрацию
high_rated = recent_published.filter(rating__gte=4)
print(high_rated)
Результат выполнения кода:
[<Article: Статья о Django>, <Article: Статья о Python>]
[<Article: Статья о Django>]
Использование нескольких менеджеров
Модель может иметь несколько менеджеров для разных целей. Это позволяет разделить логику запросов по разным контекстам использования:
from django.db import models
class UserManager(models.Manager):
def active(self):
return self.filter(is_active=True)
def admin(self):
return self.filter(is_staff=True)
class User(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
# Несколько менеджеров для разных контекстов
users = UserManager()
active_users = UserManager().active()
Рассмотрим пример использования разных менеджеров:
from myapp.models import User
# Все активные пользователи
active = User.users.active()
print(active)
# Пользователи с правами администратора
admins = User.users.admin()
print(admins)
# Активные администраторы
active_admins = User.active_users.admin()
print(active_admins)
Результат выполнения кода:
[<User: john_doe>, <User: admin>]
[<User: admin>]
[<User: admin>]
Смотрите также
-
атрибут
objects,
который является стандартным менеджером модели -
метод
get_queryset,
который возвращает базовыйQuerySetменеджера -
метод
all,
который возвращает все записи изQuerySet -
метод
filter,
который фильтрует записи вQuerySet