Как сделать функцию, которая добавляет оценку из другой модели 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