Обычно я использую метод dispatch
для представления на основе класса для установки некоторых начальных переменных или добавления некоторой логики на основе пользовательских разрешений.
Например,
from django.views.generic import FormView
from braces.views import LoginRequiredMixin
class GenerateReportView(LoginRequiredMixin, FormView):
template_name = 'reporting/reporting_form.html'
form_class = ReportForm
def get_form(self, form_class):
form = form_class(**self.get_form_kwargs())
if not self.request.user.is_superuser:
form.fields['report_type'].choices = [
choice for choice in form.fields['report_type'].choices
if choice[0] != INVOICE_REPORT
]
return form
Он работает так, как ожидалось: когда анонимный пользователь посещает страницы, вызывается метод dispatch
LoginRequiredMixin, а затем перенаправляет пользователя на страницу входа в систему.
Но если я хочу добавить некоторые разрешения для этого представления или установить некоторые начальные переменные, например,
class GenerateReportView(LoginRequiredMixin, FormView):
def dispatch(self, *args, **kwargs):
if not (
self.request.user.is_superuser or
self.request.user.is_manager
):
raise Http404
return super(GenerateReportView, self).dispatch(*args, **kwargs)
в некоторых случаях это не работает, потому что методы dispatch
для mixins, которые наследует представление, еще не были вызваны. Так, например, чтобы иметь возможность запрашивать разрешения пользователя, я должен повторить проверку с LoginRequiredMixin
:
class GenerateReportView(LoginRequiredMixin, FormView):
def dispatch(self, *args, **kwargs):
if self.request.user.is_authenticated() and not (
self.request.user.is_superuser or
self.request.user.is_manager
):
raise Http404
return super(GenerateReportView, self).dispatch(*args, **kwargs)
Этот пример прост, но иногда в смешении есть еще более сложная логика: он проверяет разрешения, делает некоторые вычисления и сохраняет их в атрибуте класса и т.д.
Теперь я разрешаю его, копируя некоторый код из mixin (как в примере выше) или копируя код из метода dispatch
представления в другой mixin и наследуя его после первого, чтобы выполнить их в (это не так, потому что этот новый mixin используется только одним видом).
Есть ли правильный способ решить такие проблемы?