Vishal Sharma
Vishal Sharma

Reputation: 57

How to do PUT request without primary key?

I'm creating a Like/Dislike api for a blog using DRF. I have Like table which contains "Post", "User" and "isLike" fields. Since Django can't have composite key, I'm using unique_together constraint for ("Post" and "User").

If a user likes a post, I create a entry in Like table. Now if a user wants to remove his like from the post or want to dislike the post, I need primary key of entry from Like table for these (PUT/DELETE) methods. Since I know "User" and "Post", and since both are unique, Can I perform (PUT/DELETE) methods with unique fields?

Model class

class LikeDislike(models.Model):
    """model for like counts"""
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    isLike = models.BooleanField()

    class Meta:
        unique_together = (("post", "user"),)

View for creating entry in Like table:

class LikeDislikeCreateView(generics.CreateAPIView):
    queryset = models.LikeDislike.objects.all()
    serializer_class = serializers.LikeDislikeSerializer

    def perform_create(self, LikeDislikeSerializer):
        LikeDislikeSerializer.save(user=self.request.user)

I can update a like/dislike using -> /like/primary-key/ but I want to do using "post" and "user" details.

Upvotes: 2

Views: 1944

Answers (2)

mehdi
mehdi

Reputation: 1150

I'm just completing @AKX answer:

class LikeDislikeCreateUpdateDeleteView(generics.RetrieveUpdateDestroyAPIView): # generics class changed!
    queryset = models.LikeDislike.objects.all()
    serializer_class = serializers.LikeDislikeSerializer

    def get_object(self):
        # if you want pass post_id and user_id in url:
        post_user = get_object_or_404(LikeDislike, post_id=self.kwargs["post_id"], user_id=self.kwargs["user_id"]) 
        # if you want pass post_id and user_id in body of request:
        post_user = get_object_or_404(LikeDislike, post_id=self.request.data["post_id"], user_id=self.request.data["user_id"])
        return post_user

    def perform_create(self, LikeDislikeSerializer):
        LikeDislikeSerializer.save(user=self.request.user)

now if you request to your url with PUT method the LikeDislikeCreateUpdateDeleteView view trying to update post_user (that came from def get_object) with LikeDislikeSerializer .and if you request to this url with DELETE method the view will delete object that is came from def get_object . hope help

Upvotes: 3

AKX
AKX

Reputation: 169268

Sure, you can – it's just a matter of overriding get_object() suitably in your views to retrieve the object to modify or delete using different parameters than the PK.

Upvotes: 5

Related Questions