LondonAppDev
LondonAppDev

Reputation: 9633

Django ClassView inheritance

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

Upvotes: 0

Views: 71

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599530

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.

Upvotes: 2

Related Questions