Ich habe einige Benutzer, die eine bestimmte Ansicht sehen dürfen.
Um es Nutzern zu ermöglichen, sich einzuloggen und sich mit einem zu beschweren 403 Forbidden
Für diejenigen Benutzer, die diese Anmeldung nicht sehen können, kann ich Folgendes verwenden (wie erklärt Hier):
@permission_required("polls.can_vote", raise_exception=True)
@login_required
def my_view(request):
...
Dies funktioniert in der Tat wie erwartet. Aber alle meine Ansichten sind klassenbasierte Ansichten. Seit Django 1.9 (endlich!) Gibt es eine ganze Reihe hübscher Mixins, um Dinge zu tun, die nur durch die Dekorateure möglich waren. Jedoch...
class MyClassView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
raise_exception = <???>
permission_required = "polls.can_vote"
template_name = "poll_vote.html"
Das funktioniert nicht. Weil das raise_exception
Flag wird von beiden verwendet LoginRequiredMixin
und PermissionRequiredMixin
Ich kann nichts einstellen.
- ob
raise_exception
istTrue
Ein Benutzer, der nicht angemeldet ist, erhält eine403 Forbidden
(was ich nicht will). - ob
raise_exception
istFalse
, ein Benutzer, der ist nicht erlaubt, die Ansicht zu sehen, wird auf die Anmeldeseite umgeleitet, die, weil der Benutzer eingeloggt ist, erneut auf die Seite umleitet. Erstellen einer Umleitungsschleife, die nicht ganz so schick ist.
Natürlich könnte ich mein eigenes Mixin implementieren, das sich erwartungsgemäß verhält, aber gibt es irgendeinen Django-Weg, dies in der Ansicht selbst zu tun? (nicht in der urls.py
)
Antworten:
6 für die Antwort № 1In vielen Fällen ist die Erhöhung von 403 für nicht authentifizierte Benutzer das erwartete Verhalten. Also ja, du brauchst eine benutzerdefinierte Mischung:
class LoggedInPermissionsMixin(PermissionRequiredMixin):
def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_authenticated():
return redirect_to_login(self.request.get_full_path(),
self.get_login_url(), self.get_redirect_field_name())
if not self.has_permission():
# We could also use "return self.handle_no_permission()" here
raise PermissionDenied(self.get_permission_denied_message())
return super(LoggedInPermissionsMixin, self).dispatch(request, *args, **kwargs)
2 für die Antwort № 2
Ich wollte einen Kommentar hinzufügen, aber mein Ruf erlaubt es nicht. Wie wäre es mit dem Folgenden? Ich fühle das unten lesbare ist?
Nach Kommentaren aktualisiert
Mein Argument ist: Du schreibst grundsätzlich modifiziert dispatch
von LoginRequiredMixin
und einfach eingestellt raise_exception = True
. PermissionRequiredMixin
werden raise PermissionDenied
wenn die richtigen Berechtigungen nicht erfüllt sind
class LoggedInPermissionsMixin(PermissionRequiredMixin):
raise_exception = True
def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_authenticated():
return redirect_to_login(self.request.get_full_path(),
self.get_login_url(),
self.get_redirect_field_name())
return super(LoggedInPermissionsMixin, self).dispatch(request, *args, **kwargs)
0 für die Antwort № 3
Die einfachste Lösung scheint eine benutzerdefinierte Ansicht zu sein. So ähnlich:
class PermissionsMixin(PermissionRequiredMixin):
def handle_no_permission(self):
self.raise_exception = self.request.user.is_authenticated()
return super(PermissionsMixin, self).handle_no_permission()
Oder, einfach benutzen PermissionRequiredMixin
wie immer und zieh das aus handle_no_premission
zu jedem CBV.