【问题标题】:Django rest framework Detail not found while deleting删除时找不到Django rest框架详细信息
【发布时间】:2022-02-07 21:43:38
【问题描述】:

我在通过 API 删除对象时遇到问题。所以我有 2 个模型,Answer 和 Vote 投票通过这样的 foreignKey 连接到 Answer

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)

现在我有一个 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):
        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)


我使用与上面相同的序列化程序*

我收到一个错误: 未找到:/api/v1/answers/55/voteDelete 没有任何回溯,事实上我已经检查过数据库中存在 answer_id 55 的投票,我可以通过 django-admin 删除它们,但不能通过 API。 你知道为什么吗?

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    第一件事 - 让我们将 get_queryset 更改为 get_object,因为您需要单个对象。然后将其简化为 answer=self.kwargs['pk'],而不是 answer_id=self.kwargs['pk']

    另一件事 - 我认为在创建新投票时删除旧投票可能会更好。您不需要序列化程序或特殊视图。只需添加到在您的视图中创建新的Vote 对象的功能:

    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.number_of_points -= old_vote.score
                answer.save()
                old_vote.delete()
    
            return super().perform_create_kwargs(user=self.request.user, answer_id=answer_id, **kwargs)
    

    【讨论】:

    • 嘿!感谢您的帮助,将 get_queryset 更改为 get_object 有帮助!但我仍然不明白我应该把 if 语句放在哪里。你的意思是在 get_object 函数中吗?因为我的 api 视图是基于类的。
    • 已编辑答案。您可以尝试将其包含在 perform_create_kwargs 方法中。您可能需要从您的models 发送至import Answer
    • 我也编辑了这个问题,如果你能检查一下这是否是你的意思?但它不会添加新的实例。我实际上想过使用预删除 django 信号来回答,以便在投票被删除之前,如果 answer.number_of_points = F('number_of_points) - instance.score,但是是的,立即添加一个新实例并清除 number_of_points 答案会方便。
    • 哦,你把它放在错误的视图中 :) 我的意思是你应该放弃 delete 视图的想法来改变投票。该函数应该在VoteCreate 类中,我认为它工作正常。编辑以避免混淆。
    • 但是是的,answer.number_of_points 已经解决了。非常感谢您的帮助!!!感激不尽
    猜你喜欢
    • 2016-01-27
    • 2017-05-15
    • 2018-02-13
    • 2020-10-11
    • 2020-11-06
    • 2021-02-19
    • 1970-01-01
    • 2021-07-01
    • 2018-08-26
    相关资源
    最近更新 更多