2017-09-16 2 views
0

Ich habe eine klassenbasierte Sicht für ein Problem Objekt. Ich möchte nur den Autor der Problem in der Lage sein, die Problem cbv anzuzeigen. Andere angemeldete Benutzer sollten auf eine verbotene Seite weitergeleitet werden.Clumsy wiederholen mich selbst Django Erlaubnis überprüfen

Ich erreiche dies durch Überprüfung der Besitz in der get_template_name() Methode. Aber wenn ich im Zusammenhang mit der verbotenen Vorlage gehen will, muss ich auch den Besitz in der get_context_data() überprüfen und den passenden Kontext herstellen.

Das funktioniert, aber es scheint wie viel zu viel semi-repetitive Code, und nur sehr nicht-Pythonic/Djangonic.

Kann jemand einen besseren Weg vorschlagen, dies zu tun? Es ist ein Problem für viele ClassBasedViews, die ich erstellt habe. Ich habe beide "Problem" -Objekte und "Brett" -Objekte, die ich das logged-in user == the author des Problem oder Board Objekts sichern möchte. Fast scheint, dass ich eine Art von Mixin oder etwas haben könnte.

Wie auch immer, hier ist ein Beispiel für meinen Ansatz:

class ProblemStudyView(UpdateView): 
    model = Problem 
    fields = "__all__" 

    def get_template_names(self): 
     problem = self.get_object() 
     if problem.author != self.request.user: 
      # User should not see this entry 
      context = {'original_author': problem.author, 'request_user': self.request.user} 
      template_name = "board/forbidden.html" 
      return template_name 
     else: 
      # This user is OK 
      template_name = "board/study.html" 
      return template_name 

    def get_context_data(self, **kwargs): 
     context = super(ProblemStudyView, self).get_context_data(**kwargs) 

     problem = self.get_object() 

     # Do the permission check a second time to setup correct context 
     if problem.author != self.request.user: 
      context = {'original_author': problem.author, 'request_user': self.request.user} 
      return context 
     else: 
      # User is ok; proceed as normal   
      return context 

Antwort

0

Sie die Berechtigung PermissionRequiredMixin und eine benutzerdefinierte nutzen könnten.

Ich würde so etwas tun:

from django.contrib.auth.mixins import PermissionRequiredMixin 


class ProblemStudyView(PermissionRequiredMixin, UpdateView): 

    model = Problem 
    fields = "__all__" 
    permission_denied_message = 'YOURMESSAGEHERE' 
    raise_exception = True 
    template_name = 'board/study.html' 

    def dispatch(self, request, *args, **kwargs): 
     self.request = request # needed for has_permission 
     self.kwargs = kwargs # needed for get_object 
     return super().dispatch(request, *args, **kwargs) 

    def has_permission(self): 
     problem = self.get_object() 
     return problem.author == self.request.user 

Da ein PermissionDeniedException angehoben wird, können Sie (oder ändern) die Standard-Django http verboten Ansicht: https://docs.djangoproject.com/en/1.11/ref/views/#the-403-http-forbidden-view

Verwandte Themen