Ниже представлена 7-я часть серии исследований классовых представлений Django (CBV), в которой рассматривается, как с помощью Mixin повторно использовать общие функции и эффективно осуществлять управление правами и проверку входа. В предыдущей статье (6-я часть) мы автоматизировали простую рендеринг страниц и перенаправление с помощью TemplateView
и RedirectView
, а теперь посмотрим, как максимизировать повторное использование и расширяемость CBV.
Перейдите по следующей ссылке на предыдущую статью!
Использование TemplateView & RedirectView
«Увеличьте повторное использование кода с помощью Django Mixin и
просто реализуйте управление правами и проверку входа!»
1. Mixin, зачем он нужен?
Django CBV сама по себе предлагает мощное повторное использование, но что делать, если в нескольких представлениях есть общие необходимые функции? Например, для доступа к определенной странице часто требуется вход или доступ только для пользователей с определенными правами. В этом случае на помощь приходит концепция Mixin.
Mixin использует концепцию множественного наследования, чтобы инъекцией одинаковых методов или свойств внедрять их в несколько классов. В Django CBV мы можем снизить дублирование кода и повысить обслуживаемость, наследуя класс Mixin с определенной функцией в класс представления.
Основные примеры использования Mixin:
- Управление правами: Проверка, вошел ли пользователь, обращающийся к определенному представлению, или обладает ли он определенными правами.
- Логика обработки форм: Логика предварительной или постобработки данных, необходимая для разных форм.
- Контекст шаблона: Добавление данных контекста, которые должны быть переданы всем представлениям.
- Логирование: Добавление функции логирования до и после выполнения определенного представления.
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
позволяют получить доступ только при наличии определенных прав или выполнении определенных условий.
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>© {{ 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, завершив нашу серию.
Посмотреть предыдущее
- Исследование классовых представлений (CBV) 1 – Причины перехода от FBV к CBV и отношение разработчика
- Исследование классовых представлений (CBV) 2 – Понимание базового класса View в Django
- Исследование классовых представлений (CBV) 3 – Простой подход к обработке форм с FormView
- Исследование классовых представлений (CBV) 4 – Использование ListView & DetailView
- Исследование классовых представлений (CBV) 5 – Реализация CRUD с помощью CreateView, UpdateView, DeleteView
- Исследование классовых представлений (CBV) 6 – Как использовать TemplateView & RedirectView
«Используйте Mixin для максимальной реализации потенциала Django CBV и
строите легкие для обслуживания и расширяемые веб-приложения!»
Комментариев нет.