Search code examples
pythondjangodecorator

make decorator Only the creator of Content can manipulate it


I have created Two decorator to block anyone to Access to specific content like:

   @method_decorator(login_required(login_url='core:login'), name='dispatch')
   @method_decorator(allowed_users(allowed_roles=['writer']), name='dispatch')
    class BookDeleteView(BSModalDeleteView):
        model = Book
        template_name = 'book/book_delete.html'
        success_message = 'Success: book was deleted.'
        success_url = reverse_lazy('core:book_list')

i want to create decorator seems like this

book=Book.objects.get(id=pk)
if request.user==book.writer.profile.user:

Solution

  • If you want to use a decorator:

    def writers_only(function):
      @wraps(function)
      def wrap(request, *args, **kwargs):
            if request.user == Book.objects.get(id=kwargs.get('pk')).writer.profile.user:
                return function(request, *args, **kwargs)
            else:
                # Do something else 
      return wrap
    

    Then add this to your class based view:

    # Other decorators
    @method_decorator(writers_only, name='dispatch')
    class BookDeleteView(BSModalDeleteView):
        # Your code
    

    Otherwise you can also override BookDeleteView.get_object (you can create a mixin to reuse this implementation of get_object in various views):

    @method_decorator(login_required(login_url='core:login'), name='dispatch')
    @method_decorator(allowed_users(allowed_roles=['writer']), name='dispatch')
        class BookDeleteView(BSModalDeleteView):
            model = Book
            template_name = 'book/book_delete.html'
            success_message = 'Success: book was deleted.'
            success_url = reverse_lazy('core:book_list')
            
            def get_object(self, *args, **kwargs):
                obj = super().get_object(*args, **kwargs)
                if obj.writer.profile.user != self.request.user:
                    raise PermissionDenied() # Or do something else
                return obj