0

I have the following views which are working fine:

class FriendView(View):

    message_success = None
    message_error = None

    def get_pending_received(self):
        return models.FriendRequest.objects.filter(recipient_user_id=self.request.user.id)

    def get_existing_friends(self):
        return models.Friendship.objects.filter(source_user_id=self.request.user.id)

    def get_pending_sent(self):
        return models.FriendRequest.objects.filter(sender_user_id=self.request.user.id)

    def get(self, request):
        return render(request, 'template/friends.html',
                      {'pending_received_requests': self.get_pending_received(),
                       'existing_friends': self.get_existing_friends(),
                       'pending_sent_requests': self.get_pending_sent(),
                       'message_success': self.message_success,
                       'message_error': self.message_error})



class DeleteFriendView(FriendView):



    def get(self, request, friendship_id):
        try:
            friendship = models.Friendship.objects.get(id=friendship_id)
        except models.Friendship.DoesNotExist:
            raise Http404

        if not ((friendship.source_user_id == request.user.id) or (friendship.dest_user_id == request.user.id)):
            return HttpResponseForbidden("Forbidden")

        friendship.delete()

        message_success = "Friend has been deleted"

        return render(request, 'template/friends.html',
                      {'pending_received_requests': self.get_pending_received(),
                       'existing_friends': self.get_existing_friends(),
                       'pending_sent_requests': self.get_pending_sent(),
                       'message_success': 'Friend has been Deleted'})   

My question is, is there a way to put the logic in the DeleteFriendView that is execute before get() without overriding get()? This would be cleaner and would reduce duplicate code but after reading the ClassView documentation I can't seem to figure out the best way to do this, since I can't access self outside of a method in the class view?

I would imagine something like this:

class DeleteFriendView(FriendView):
    def before_get(self):
        try:
            friendship = models.Friendship.objects.get(id=friendship_id)
        except models.Friendship.DoesNotExist:
            raise Http404

        if not ((friendship.source_user_id == request.user.id) or (friendship.dest_user_id == request.user.id)):
            return HttpResponseForbidden("Forbidden")

        friendship.delete()

        self.message_success = "Friend has been deleted"

This way the get() method could be reused.

Thanks, Mark

1 Answer 1

2

Why don't you want to override get()? You can put your logic there, then simply call the superclass method.

class DeleteFriendView(FriendView):
    def get(self, request):
        # delete-specific logic here

        # now call FriendView get()
        return super(DeleteFriendView, self).get(request)

Note by the way that it's very poor practice to put data-modifying actions in a GET request. They're far too easy to trigger by accident, or via malicious links. You should always put things like deletion in a POST request.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Daniel. Is it better to create forms with hidden values to do actions like this then?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.