Ниже представлена 7-я часть серии исследований классовых представлений Django (CBV), в которой рассматривается, как с помощью Mixin повторно использовать общие функции и эффективно осуществлять управление правами и проверку входа. В предыдущей статье (6-я часть) мы автоматизировали простую рендеринг страниц и перенаправление с помощью TemplateView и RedirectView, а теперь посмотрим, как максимизировать повторное использование и расширяемость CBV.

Перейдите по следующей ссылке на предыдущую статью!

Использование TemplateView & RedirectView


«Увеличьте повторное использование кода с помощью Django Mixin и

просто реализуйте управление правами и проверку входа!»


1. Mixin, зачем он нужен?

Схема Mixin – Структура класса с собранными функциональными блоками

Django CBV сама по себе предлагает мощное повторное использование, но что делать, если в нескольких представлениях есть общие необходимые функции? Например, для доступа к определенной странице часто требуется вход или доступ только для пользователей с определенными правами. В этом случае на помощь приходит концепция Mixin.

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

Основные примеры использования Mixin:

  1. Управление правами: Проверка, вошел ли пользователь, обращающийся к определенному представлению, или обладает ли он определенными правами.
  2. Логика обработки форм: Логика предварительной или постобработки данных, необходимая для разных форм.
  3. Контекст шаблона: Добавление данных контекста, которые должны быть переданы всем представлениям.
  4. Логирование: Добавление функции логирования до и после выполнения определенного представления.

2. Применение самых известных Mixin в Django: LoginRequiredMixin

Одним из самых часто используемых Mixin является LoginRequiredMixin. Как следует из названия, он заставляет пользователя обязательно войти, чтобы получить доступ к этому представлению.

2.1 Как использовать LoginRequiredMixin

LoginRequiredMixin включен в модуль django.contrib.auth.mixins.

# views.py
from django.views.generic import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Post # Пример модели

class MyPostListView(LoginRequiredMixin, ListView):
    model = Post
    template_name = 'posts/my_posts.html'
    context_object_name = 'posts'

    # URL для перенаправления, если пользователь не вошел (опционально)
    # login_url = '/accounts/login/' # значение по умолчанию – settings.LOGIN_URL
    # redirect_field_name = 'next'  # имя параметра запроса, используемого для возврата на исходную страницу после входа (значение по умолчанию)
  • Порядок наследования: Сначала наследуется LoginRequiredMixin, затем наследуется классовое представление Django (в данном случае ListView). Mixin обычно используется для добавления функций, поэтому его принято ставить перед основным классом представления.
  • LoginRequiredMixin автоматически перенаправляет пользователей, которые не вошли в систему, на страницу входа, указанную в settings.LOGIN_URL. После успешного входа они перенаправляются обратно на страницу, с которой были перенаправлены, через параметр запроса next.

2.2 Подключение в urls.py

Представления с применением LoginRequiredMixin подключаются к urls.py так же, как и обычные CBV.

# urls.py
from django.urls import path
from .views import MyPostListView

urlpatterns = [
    path('my-posts/', MyPostListView.as_view(), name='my_posts'),
]

Теперь при переходе по пути /my-posts/, если пользователь не вошел, он будет перенаправлен на страницу входа.


3. Mixin для управления правами: PermissionRequiredMixin & UserPassesTestMixin

Если LoginRequiredMixin заставляет входить в систему, то PermissionRequiredMixin и UserPassesTestMixin позволяют получить доступ только при наличии определенных прав или выполнении определенных условий.

Схема Login & PermissionMixin – Проверка прав доступа

3.1 Как использовать PermissionRequiredMixin

Взаимодействует с системой прав Django, чтобы только пользователи с определенным permission могли получить доступ.

# views.py
from django.views.generic import CreateView
from django.contrib.auth.mixins import PermissionRequiredMixin
from .models import Article
from .forms import ArticleForm

class ArticleCreateView(PermissionRequiredMixin, CreateView):
    model = Article
    form_class = ArticleForm
    template_name = 'articles/article_form.html'
    success_url = '/articles/'

    # Указываем права в формате 'app_label.permission_codename'
    permission_required = 'app_label.add_article'
    # Чтобы разрешить при наличии хотя бы одного из множества прав:
    # permission_required = ('app_label.add_article', 'app_label.change_article')
    # raise_exception = True # возникает ошибка 403 Forbidden при отсутствии прав (по умолчанию перенаправление на страницу входа)
  • permission_required: Указывает необходимые права в виде строки (одной или кортежа). Обычно используются права, автоматически создаваемые приложением auth для каждой модели (add_model, change_model, delete_model, view_model).

3.2 Как использовать UserPassesTestMixin

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

# views.py
from django.views.generic import UpdateView
from django.contrib.auth.mixins import UserPassesTestMixin
from .models import Comment
from .forms import CommentForm

class CommentUpdateView(UserPassesTestMixin, UpdateView):
    model = Comment
    form_class = CommentForm
    template_name = 'comments/comment_form.html'
    success_url = '/comments/'

    # Переопределяем метод test_func для проверки условий
    def test_func(self):
        comment = self.get_object()
        # Проверка, является ли текущий вошедший пользователь автором комментария
        return self.request.user == comment.author or self.request.user.is_superuser

    # raise_exception = True # возникает ошибка 403 Forbidden при неудаче в проверке
  • test_func(): Если переопределенный метод возвращает True, предоставляется доступ, а если False, доступ отклоняется.
  • self.request.user: Позволяет получить текущий объект пользователя, который вошел в систему.

4. Создание пользовательского Mixin

Кроме примеров Mixin, предоставленных в Django, вы также можете создавать свой собственный Mixin, который можно будет повторно использовать в нескольких представлениях. Например, давайте создадим Mixin, который добавляет контекст current_year, необходимый для всех страниц.

# common/mixins.py
from datetime import datetime

class CurrentYearMixin:
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['current_year'] = datetime.now().year
        return context

# views.py (пример применения)
from django.views.generic import TemplateView
from .common.mixins import CurrentYearMixin

class MyCustomPageView(CurrentYearMixin, TemplateView):
    template_name = 'my_custom_page.html'

# my_custom_page.html (использование в шаблоне)
<footer>&copy; {{ current_year }} My Website</footer>
  • CurrentYearMixin переопределяет метод get_context_data, чтобы добавить current_year в контекст. Важно вызывать super().get_context_data(**kwargs), чтобы сохранить данные контекста от родительского класса (или другого Mixin).

5. Сравнение с FBV

Функция FBV (представления на основе функций) CBV + Mixin
Проверка входа/прав @login_required, @permission_required декораторы. <br> Пользовательские условия пишутся непосредственно в функции, например: if not request.user.is_authenticated: return redirect(...). Простое применение через наследование LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin и прочие. <br> Похоже на декораторы, но более интегрировано в структуру CBV.
Повторное использование кода Общую логику можно выделить в отдельные функции или написать свои декораторы. <br> Легко возникнет дублирование кода. С помощью Mixin можно модульно организовать необходимые функции и внедрить их через множественное наследование. <br> Структурированность и высокая степень повторного использования.
Читаемость кода Повторяющиеся условия могут встречаться в каждой функции. Легко определить, какие функции (права, вход и т. д.) применяются, просто взглянув на список наследования классов.
Обслуживаемость При добавлении новых функций может понадобиться редактировать несколько функций. Достаточно изменить только класс Mixin, и это автоматически применится ко всем представлениям, использующим этот Mixin.
Производительность разработки (ключевые слова) «Индивидуальная обработка для каждой функции, вероятность повторяющихся задач» «Модульная структура, легкость в расширении функций, соблюдение принципа DRY (Не повторяйте себя), повышение продуктивности»

6. Заключение и анонс следующей части

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

Теперь мы рассмотрели почти все основные аспекты Django CBV - от базового использования до сложного CRUD и расширения функций с помощью Mixin.

В следующей части (8-й части серии) мы планируем обобщить, как применить изученные CBV в реальных проектах, как на практике комбинировать их в сложных сценариях, а также проанализируем преимущества и ограничения CBV, завершив нашу серию.


Посмотреть предыдущее

  1. Исследование классовых представлений (CBV) 1 – Причины перехода от FBV к CBV и отношение разработчика
  2. Исследование классовых представлений (CBV) 2 – Понимание базового класса View в Django
  3. Исследование классовых представлений (CBV) 3 – Простой подход к обработке форм с FormView
  4. Исследование классовых представлений (CBV) 4 – Использование ListView & DetailView
  5. Исследование классовых представлений (CBV) 5 – Реализация CRUD с помощью CreateView, UpdateView, DeleteView
  6. Исследование классовых представлений (CBV) 6 – Как использовать TemplateView & RedirectView

«Используйте Mixin для максимальной реализации потенциала Django CBV и

строите легкие для обслуживания и расширяемые веб-приложения!»