Django: eine klassenbasierte Ansicht mit Mixins und Versandmethode
ormalerweise benutze ich eindispatch
Methode einer klassenbasierten Ansicht, um einige anfängliche Variablen festzulegen oder eine Logik basierend auf den Berechtigungen des Benutzers hinzuzufügen.
Beispielsweise
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
Es funktioniert wie erwartet: Wenn ein anonymer Benutzer eine Seite besucht, wird dasdispatch
Methode von LoginRequiredMixin wird aufgerufen und leitet den Benutzer dann zur Anmeldeseite weiter.
Aber wenn ich Berechtigungen für diese Ansicht hinzufügen oder anfängliche Variablen festlegen möchte, z. B.
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)
in einigen Fällen funktioniert es nicht, weildispatch
Methoden der Mixins, die die View erbt, wurden noch nicht aufgerufen. Damit ich zum Beispiel nach den Berechtigungen des Benutzers fragen kann, muss ich die Überprüfung von @ wiederholeLoginRequiredMixin
:
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)
Dieses Beispiel ist einfach, aber manchmal enthält ein Mixin etwas kompliziertere Logik: Es prüft auf Berechtigungen, führt Berechnungen durch und speichert sie in einem Klassenattribut usw.
Für jetzt löse ich es, indem ich einen Code aus dem Mixin kopiere (wie im obigen Beispiel) oder indem ich den Code aus dem @ kopiedispatch
Methode der Ansicht auf ein anderes Mixin und Vererben nach dem ersten, um sie in der richtigen Reihenfolge auszuführen (was nicht so hübsch ist, da dieses neue Mixin nur von einer Ansicht verwendet wird).
Gibt es einen geeigneten Weg, um diese Art von Problemen zu lösen?