В предыдущем посте я рассказал, как работать с данными с помощью ORM Django, то есть о CRUD (Create, Read, Update, Delete) операциях. На этот раз я хочу более глубоко проанализировать, что такое objects менеджер, как он устроен и что он может делать. objects — это важная концепция, которую необходимо знать для правильного понимания ORM Django.


1. Что такое objects менеджер?

Наиболее часто встречающимся элементом в базовой структуре модели Django является менеджер с именем objects. objects называется менеджером моделей Django (Manager) и отвечает за запросы и манипулирование записями в базе данных. Проще говоря, objects менеджер действует как мост между классом модели и базой данных.

Схема менеджера объектов Django

Базовое свойство класса модели objects является экземпляром класса Manager, предоставляемого Django. С помощью этого экземпляра осуществляется взаимодействие с базой данных, выполняя операции создания, поиска, изменения и удаления данных. Например, вы можете получить доступ к данным, используя методы, такие как Post.objects.all() или Post.objects.create().


2. Роль класса Manager

Manager класс является интерфейсом базы данных, который по умолчанию предоставляется модели Django. С его помощью можно выполнять различные запросы. По умолчанию Django автоматически создаёт objects менеджер с именем Manager для каждой модели, и этот Manager используется для выполнения большинства операций CRUD.

Вы, возможно, уже знакомы с тем, как CRUD реализуется через objects. Примеры кода были рассмотрены в предыдущем посте, поэтому здесь я пропущу этот момент.


3. Создание кастомного менеджера

Хотя стандартный objects менеджер весьма полезен, иногда необходимо повторно использовать конкретную логику запросов или выполнять более сложные выборки. В таких случаях можно создать кастомный менеджер, чтобы добавить нужные функции.

3.1 Определение кастомного менеджера

Например, давайте создадим кастомный менеджер, который будет фильтровать только опубликованные посты.

from django.db import models

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='published')

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    status = models.CharField(max_length=10, choices=[('draft', 'Draft'), ('published', 'Published')])
    publish_date = models.DateTimeField(auto_now_add=True)

    # Добавление кастомного менеджера помимо стандартного objects
    published = PublishedManager()

В приведённом примере мы определили кастомный менеджер с именем PublishedManager и добавили его в модель Post. Этот PublishedManager возвращает только те посты, статус которых 'published'. Теперь, если вызвать Post.published.all(), вы получите только опубликованные посты.

3.2 Применение кастомного менеджера

  • Снижение дублирования кода: Вместо того чтобы каждый раз добавлять условия фильтрации, использование кастомного менеджера позволяет уменьшить дублирование кода.
  • Инкапсуляция специализированной логики запросов: Можно кастомизировать логику запросов в соответствии с определённой бизнес-логикой и управлять ею аккуратно внутри модели.

4. Разнообразные операции с помощью objects менеджера

Менеджер objects Django поддерживает множество операций с базой данных, помимо стандартных CRUD функций.

4.1 Фильтрация данных

  • filter(): Получает несколько объектов, соответствующих заданным условиям.
    published_posts = Post.objects.filter(status='published')
  • exclude(): Получает объекты, которые не соответствуют определённому условию.
    draft_posts = Post.objects.exclude(status='published')

4.2 Сортировка и срезы

  • Сортировка: Вы можете отсортировать данные с помощью метода order_by().
    recent_posts = Post.objects.all().order_by('-publish_date')
  • Срезы: Как и в списках Python, вы можете использовать срезы в queryset для получения данных в определенном диапазоне.
    first_three_posts = Post.objects.all()[:3]

4.3 Использование агрегатных функций

Менеджер objects также предоставляет агрегатные функции. Например, если вы хотите узнать количество постов, вы можете использовать метод count().

post_count = Post.objects.count()

Кроме того, вы также можете выполнять агрегированные операции, такие как среднее и сумма с помощью метода aggregate().

from django.db.models import Avg
average_length = Post.objects.aggregate(Avg('content_length'))

5. Принцип работы менеджера objects

Менеджер objects внутренне создает объект, называемый QuerySet. QuerySet представляет собой набор запросов для получения данных из базы данных. Каждый раз, когда вызываются методы такие как objects.all() или objects.filter(), Django создает QuerySet и при необходимости передает соответствующий запрос в базу данных для получения результата.

QuerySet использует ленивую оценку (lazy evaluation). Это означает, что фактический доступ к базе данных осуществляется не при создании QuerySet, а только в момент, когда данные действительно нужны, когда выполняется запрос к базе данных. Это позволяет избежать излишних запусков запросов и вести эффективную обработку данных.


Завершая этот пост

Менеджер objects Django — это мощный инструмент, который упрощает взаимодействие с базой данных и помогает проще работать с данными. Помимо стандартных CRUD функций, вы можете определить кастомные менеджеры для повторного использования конкретной логики запросов или упрощения более сложных операций. Кроме того, благодаря особенностям, таким как ленивая оценка QuerySet, обработка данных также становится более эффективной.

Глубокое понимание менеджера objects ORM Django позволит вам более эффективно работать с базой данных, уменьшать дублирование кода и поддерживать код в чистоте. Постепенно начните увеличивать степень использования менеджера моделей и внедряйте кастомные менеджеры по мере необходимости. Это сделает сложную обработку данных в веб-приложениях намного проще и гибче.

В следующем посте мы подробно разберём QuerySet и извлечение данных. Одним из преимуществ ORM является то, что "не нужно знать SQL", и чтобы по-настоящему использовать это преимущество, информация из следующего поста будет очень важна. Ожидайте следующую статью.