Django rest framework Деталь не найдена при удалении
У меня проблема с удалением объекта через API. У меня есть 2 модели, Answer и Vote голосование связано с Answer через foreignKey следующим образом
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',)
Теперь у меня есть конечная точка API для создания голосования для пользователя по определенному ответу
path('answers/<int:pk>/vote', VoteCreate.as_view()),
Выглядит следующим образом:
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):
return super().perform_create_kwargs(user=self.request.user, answer_id=self.kwargs['pk'], **kwargs)
И я также хочу удалить то же голосование, используя url, как это
path('answers/<int:pk>/voteDelete', VoteDelete.as_view()),
Потому что я знаю, что только 1 пользователь (request.user) может иметь 1 голос за ответ. Поэтому я попытался сделать это аналогично созданию
class VoteDelete(generics.DestroyAPIView):
serializer_class = VoteDeleteSerializer
def get_queryset(self):
queryset = Vote.objects.get(user=self.request.user, answer_id=self.kwargs['pk'])
return queryset
Я использую тот же сериализатор, что и выше*
Я получаю ошибку: Not Found: /api/v1/answers/55/voteDelete Нет никакого отслеживания, я проверил, что в базе данных Vote с answer_id 55 существует и я могу удалить их через django-admin, но не могу через API. У вас есть идеи, почему?
Первое - давайте изменим get_queryset на get_object, потому что вам нужен один объект. Затем вместо answer_id=self.kwargs['pk'] упростим до answer=self.kwargs['pk'].
Другой момент - я думаю, что было бы лучше удалить старое голосование при создании нового. Для этого вам не нужен сериализатор или специальное представление. Просто добавьте функцию в представление:
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()