如何将字段添加到 Django 查询集中

How to add field to Django queryset

我正在学习 DRF 并尝试制作网站,用户可以在网站上留下对某些产品的评论,还可以对这些评论进行评分(喜欢或不喜欢)。 所以现在我陷入了类似的系统。例如我有这些模型:

class Review(models.Model):
    author = models.ForeignKey(User)
    text = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

class Reaction(models.Model):
    author = models.ForeignKey(User)
    review = models.ForeignKey(Review, related_name='reactions')
    like = models.BooleanField()  # True = like, False = dislike

我想显示带有喜欢和不喜欢计数器的 post 列表,并且还想以某种方式标记登录用户已经喜欢或不喜欢 post。 我想用计数器列出 posts,但不知道如何包含有关 post 的信息已被用户评分。

class ListReviews(generics.ListAPIView):
    serializer_class = ProductReviewSerializer

    def get_queryset(self):
        product_slug = self.kwargs['product_slug']
        queryset = Review.objects.filter(product__slug=product_slug).annotate(
                likes_count=Count('reactions', filter=Q(reactions__like=True)),
                dislikes_count=Count('reactions', filter=Q(reactions__like=False)),
                user_reaction=...
                )
        return queryset

有可能吗?或者最好只创建另一个端点来获取用户对当前页面的反应?

这可以使用 Subquery 来完成,选择由当前用户过滤的评论并将其用作注释

# You'll need these imports
from django.db.models import Q, Count, OuterRef, Subquery

def get_queryset(self):
    product_slug = self.kwargs['product_slug']
    user_reactions = Reaction.objects.filter(review=OuterRef('pk'), author=self.request.user)
    queryset = Review.objects.filter(product__slug=product_slug).annotate(
        likes_count=Count('reactions', filter=Q(reactions__like=True)),
        dislikes_count=Count('reactions', filter=Q(reactions__like=False)),
        user_reaction=Subquery(user_reactions.values('like')[:1])
    )
    return queryset

当用户喜欢评论、不喜欢评论或没有反应时,user_reaction 注释将分别为 True、False 或 None