Django База [2023]: Свой кастомный менеджер модели Django #14
Django

Django База [2023]: Свой кастомный менеджер модели Django #14

Razilator

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

В прошлом уроке мы рассмотрели методы QuerySet встроенного менеджера модели Django.

Создание своего менеджера модели

Переходим к самой модели Article в файле models.py, в приложении blog.

И вставляем необходимый код для обработки статуса у метода all() для модели статей, чтобы понять, что такое метод менеджера all(), рекомендую ознакомиться с прошлым уроком.

blog/models.py
class Article(models.Model):
    """
    Модель постов для сайта
    """
    
    class ArticleManager(models.Manager):
        """
        Кастомный менеджер для модели статей
        """

        def all(self):
            """
            Список статей (SQL запрос с фильтрацией для страницы списка статей)
            """
            return self.get_queryset().filter(status='published')

    STATUS_OPTIONS = (
        ('published', 'Опубликовано'), 
        ('draft', 'Черновик')
    )

    title = models.CharField(verbose_name='Заголовок', max_length=255)
    category = TreeForeignKey('Category', on_delete=models.PROTECT, related_name='articles', verbose_name='Категория')

    # Другие поля модели
    
    objects = ArticleManager()
    
    # Методы модели... 

Отлично, мы создали кастомный менеджер, переопределив стандартный менеджер objects модели Article.

По желанию мы можем не переопределять менеджер модели, а создать ещё один менеджер, например custom = ArticleManager() и обращаться к нему следующим образом: Article.custom.all()

Примечание: если вы решили сделать менеджер модели custom, то вам необходимо поменять вызовы модели в представлениях на свой менеджер. Сделать это можно через добавление параметра queryset к ListView, DetailView:

blog/views.py
class ArticleListView(ListView):
    model = Article
    template_name = 'blog/articles_list.html'
    context_object_name = 'articles'
    paginate_by = 2
    queryset = Article.custom.all()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Главная страница'
        return context

Проверка менеджера в списке статей

Теперь давайте одну из наших статей сделаем черновиком, и посмотрим, выведется ли она в списке статей:

Делаем статус статьи как черновик
Делаем статус статьи как черновик

Переходим на главную:

Десятой статьи нет
Десятой статьи нет

Ну и как видите, статья со статусом черновика не вывелась. Отлично, этого мы и хотели.

;