Django 5 для начинающих

Прогресс по курсу:  9/1004

10.11 Использование миксинов в работе с представлениями Django
2 из 3 шагов пройдено
0 из 3 баллов  получено

Что такое миксины?

Как мы уже знаем, как два представления Django на основе классов построены из миксинов, которые обеспечивают изолированную функциональность. Они позволяют объединить общие функциональности и методы в одном классе, который затем можно использовать в других классах или моделях. Миксины добавляют дополнительные возможности и функционал к нашим классам, без необходимости повторного написания кода.

Мы рассмотрим, DetailView кто создает подробное представление объекта и ListView кто создает список объектов, обычно из набора запросов, с необязательной разбивкой на страницы. Это приведет нас к рассмотрению четырех миксинов, которые в сочетании обеспечивают полезную функциональность при обработке одного объекта Django или набора объектов.

Существуют также классы миксинов и в общих представлениях редактирования ( FormView и представлениях CreateView , UpdateView и DeleteView ).

 

Стандартные миксины Django

Для безопасности проекта мы можем использовать встроенные миксины, которые запрещают неавторизованным пользователям добавлять материал. На этот случай в Django существует миксин LoginRequiredMixin, который дает возможность добавлять материалы только после авторизации пользователя на сайте.

В разделе 10.9 "Работа с CreateView" мы реализовали добавление статьи с помощью представления CreateView. Давайте наше представление дополним, добавив в него миксин LoginRequiredMixin.

from django.contrib.auth.mixins import LoginRequiredMixin

class PostCreateView(LoginRequiredMixin, CreateView):
    """
    Представление: создание материалов на сайте
    """
    model = Post
    template_name = 'blog/post_create.html'
    form_class = PostCreateForm
    login_url = 'home'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = 'Добавление статьи на сайт'
        return context

    def form_valid(self, form):
        form.instance.author = self.request.user
        form.save()
        return super().form_valid(form)

По сути, мы "подмешали" миксин к классу CreateView, дополнив код представления как под капотом, так и добавили свойство для ссылки авторизации пользователя, так как у нас пока нет авторизации, мы будем перенаправлять пользователя на главную страницу сайта.

Давайте проверим в деле, как это работает. Запустим сервер и через админ панель выйдем из аккаунта. Теперь попробуем добавить статью, перейдя по следующему адресу: http://127.0.0.1:8000/post/create/. Автоматически, меня перебрасывает на страницу всех статей со статусом HTTP 302.

В консоли Django мы увидим следующее:

[26/Nov/2023 14:19:08] "GET /post/create/ HTTP/1.1" 302 0

А в браузере мы будем перенаправлены по адресу http://127.0.0.1:8000/?next=/post/create/

Рассмотрим миксин уведомления для представления обновления материала. Для этого мы будем использовать встроенный миксин SuccessMessageMixin при отправке формы.

from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin

class PostUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
    """
    Представление: обновления материала на сайте
    """
    model = Post
    template_name = 'blog/post_update.html'
    context_object_name = 'post'
    form_class = PostUpdateForm
    login_url = 'home'
    success_message = 'Запись была успешно обновлена!'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = f'Обновление статьи: {self.object.title}'
        return context

    def form_valid(self, form):
        # form.instance.updater = self.request.user
        form.save()
        return super().form_valid(form)

В примере выше мы использовали два миксина, один для неавторизованных пользователей, и один для уведомления при успешном обновлении материала, также этот миксин можно добавить и к представления добавления материала.

Нам необходимо настроить шаблон уведомления, для этого в папке templates создадим папку includes, и в нее добавим шаблон messages.html со следующим кодом:

{% if messages %}
{% for message in messages %}
    <div class="alert alert-{% if message.tags %}{{ message.tags }}{% endif %} alert-dismissible fade show" role="alert">
        <i class="fas fa-info-circle"></i> {{message}}
        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
    </div>
{% endfor %}
{% endif %}

Шаблон мы используем из Bootstrap, а сами теги из документации по django.contrib.messages

Далее нам необходимо подключить компонент messages в main.html, поэтому обновляем содержимое:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
            crossorigin="anonymous"></script>
</head>
<body>
{% include 'header.html' %}
<div class="container">
    <div class="row">
        <div class="col-lg-8 p-4">
        {% include 'includes/messages.html' %}
            {% block content %}
            {% endblock %}
            {% include 'pagination.html' %}
        </div>
        <div class="col-4 p-4">
            {% include 'sidebar.html' %}
        </div>
    </div>
</div>
{% include 'footer.html' %}
</body>
</html>

Отлично, теперь давайте обновим одну из наших статей и посмотрим как работает миксин уведомления. Запустим сервер, перейдем в панель администратора и авторизуемся. Далее откроем http://127.0.0.1:8000 и перейдем в любую запись. И в адресной строке добавим /update/ к пути.

Обновив запись мы увидим следующее сообщение: 

Мы видим что все прекрасно работает, в следующем шаге мы попробуем добавить кастомный миксин, с помощью которого редактировать записи сможет только администратор или автор записи.


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

В разделе 10.10:

В этом разделе:

Внезапно имя объекта изменилось.

Хотя его вообще можно не указывать (будет post по умолчанию)

Изменен ilya kutaev

@ilya_kutaev, исправил, спасибо.