Как сделать функцию, которая добавляет оценку из другой модели Django

Я хочу сделать Api для добавления баллов к ответу, поэтому я создал эту модель для защиты пользователя от добавления 2 баллов к ответу:

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)

у меня есть простой набор представлений и сериализатор

class Vote(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)

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__'

И это работает, но я хочу убедиться, что каждый раз, когда я публикую этот api, оценка добавляется к Answer.number_of_points. У вас есть идеи, как это сделать?

Вы можете переопределить метод create Serializer для обновления поля number_of_points модели Answer. Если вы хотите обеспечить atomacity, вы можете добавить transaction.atomicдекоратор к create функции. docs

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__'

    @transaction.atomic # if you want ensure atomicity
    def create(self, validated_data):
        vote = super().create(validated_data)
        answer = vote.answer
        answer.number_of_points += vote.score
        answer.save()
        return vote

Вернуться на верх