Обновление поля в методе сохранения другой модели с помощью F()

Я пытаюсь создать систему голосования, в которой оценка данного сообщения не зависит от типа голосов, отданных пользователями. В случае, если пользователь удаляет профиль, данный балл не должен увеличиваться/уменьшаться из-за того, что его голос был удален. Поэтому оценки обновляются только с помощью выражения F('score') + 1 или F('score') - 1.

Within Vote.save(), я пытаюсь реализовать это, но поле Question.score не обновляется при создании Vote. Как я могу получить тест, в котором оценка в вопросе изменяется от 0 до 1? django.db.models.F фактически импортируется в модуль, но не отображается здесь.

class TestQuestionScoreUpVote(TestCase):
    '''Verify that a Question's score increments by one point
    when the Vote is an "up" vote.'''

    @classmethod
    def setUpTestData(cls):
        tag1 = Tag.objects.create(name="Tag1")
        user = get_user_model().objects.create_user("TestUser")
        profile = Profile.objects.create(user=user)
        cls.question = Question.objects.create(
            title="Question__001",
            body="Content of Question 001",
            profile=profile
        )
        cls.question.tags.add(tag1)
        user_vote = Vote.objects.create(
            profile=profile, type="upvote", content_object=cls.question
        )

    def test_new_user_vote_on_question(self):
        self.assertEqual(self.question.score, 1)

class Post(Model):

    body = TextField()
    date = DateField(default=date.today)
    comment = ForeignKey('Comment', on_delete=CASCADE, null=True)
    profile = ForeignKey(
        'authors.Profile', on_delete=SET_NULL, null=True,
        related_name='%(class)ss',
        related_query_name="%(class)s"
    )
    vote = GenericRelation(
        'Vote', related_query_name="%(class)s"
    )
    score = IntegerField(default=0)


    class Meta:
        abstract = True


class Question(Post):

    title = CharField(max_length=75)
    tags = ManyToManyField(
        'Tag', related_name="questions", related_query_name="question"
    )
    views = IntegerField(default=0)
    objects = Manager()
    postings = QuestionSearchManager()


    class Meta:
        db_table = "question"
        ordering = ["-score" , "-date"]


    def __repr__(self):
        return f"{self.__class__.__name__}(title={self.title})"


class Vote(Model):

    profile = ForeignKey(
        'authors.Profile', on_delete=SET_NULL, null=True,
        related_name="votes"
    )
    type = CharField(max_length=7)
    content_type = ForeignKey(ContentType, on_delete=CASCADE)
    object_id = PositiveIntegerField()
    content_object = GenericForeignKey()

    def save(self, *args, **kwargs):
        post = ContentType.objects.get_for_id(
            self.content_type_id
        ).get_object_for_this_type(id=self.object_id)
        if self.type == "upvote":
            post.score = F("score") + 1
        else:
            post.score = F("score") - 1
        post.refresh_from_db()
        super().save(*args, **kwargs)

Вы забываете вызвать post.save() после изменения объекта:

def save(self, *args, **kwargs):
        post = ContentType.objects.get_for_id(
            self.content_type_id
        ).get_object_for_this_type(id=self.object_id)
        if self.type == "upvote":
            post.score = F("score") + 1
        else:
            post.score = F("score") - 1
        post.save() # <- HERE
        post.refresh_from_db()
        super().save(*args, **kwargs)
Вернуться на верх