Home > Software design >  Django rest framework Detail not found while deleting
Django rest framework Detail not found while deleting

Time:02-07

i have a a problem deleting an object via API. So i have 2 models, Answer and Vote vote is connected to Answer via foreignKey like this

class Vote(models.Model):
    class AnswerScore(models.IntegerChoices):
        add = 1
        subtract = -1

    score = models.IntegerField(choices=AnswerScore.choices)
    answer = models.ForeignKey('Answer', on_delete=models.PROTECT)
    user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)

    class Meta:
        unique_together = ('answer', 'user',)

class Answer(models.Model):
    answer = models.TextField()
    created_at = models.DateTimeField(editable=False, default=timezone.now)
    updated_at = models.DateTimeField(default=timezone.now)
    user = models.ForeignKey('users.CustomUser', on_delete=models.PROTECT)
    question = models.ForeignKey('Question', on_delete=models.PROTECT)
    number_of_points = models.IntegerField(default=0)
    moderate_status = models.BooleanField(default=False)

Now i have an API endpoint for creating a Vote for user on a particular answer

    path('answers/<int:pk>/vote', VoteCreate.as_view()),

Looks like this:

class VoteSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    answer = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Vote
        fields = '__all__'


class VoteCreate(ParentKeyAPIView, generics.CreateAPIView):
    model = Vote
    parent_model_field = 'answer_id'
    serializer_class = VoteSerializer

    def perform_create_kwargs(self, **kwargs):
        answer_id = self.kwargs['pk']
        answer = Answer.objects.get(id=int(answer_id))

        if Vote.objects.filter(user=self.request.user, answer=answer).exists():
            old_vote = Vote.objects.get(user=self.request.user, answer=answer)
            answer -= old_vote.score
            answer.save()
            old_vote.delete()

        return super().perform_create_kwargs(user=self.request.user, answer_id=answer_id, **kwargs)


Im using the same serializer just like above*

I get an error: Not Found: /api/v1/answers/55/voteDelete There is no any traceback, i have checked in fact that in database the Vote with answer_id 55 exists and i can delete them via django-admin but cant via API. Do you have any idea why?

CodePudding user response:

First thing - let's change get_queryset to get_object, because you want single object. Then instead of answer_id=self.kwargs['pk'] simplify it to answer=self.kwargs['pk'].

Another thing - I think it's might be better to delete old vote while creating new one. You don't need serializer or special view for that. Just add to function creating new Vote object in your view:

class VoteCreate(...):
    ...
    def perform_create_kwargs(self, **kwargs):
        answer_id = self.kwargs['pk']
        answer = Answer.object.get(id=int(answer_id))

        if Vote.objects.filter(user=self.request.user, answer=answer).exists():
            old_vote = Vote.objects.get(user=self.request.user, answer=answer)
            answer -= old_vote.score
            answer.save()
            old_vote.delete()

        return super().perform_create_kwargs(user=self.request.user, answer_id=answer_id, **kwargs)
  •  Tags:  
  • Related