Django Rest DRF:获取反向关系的对象数

Django Rest DRF : getting count of objects for reverse relation

假设我有两个模型。

Model

class Item(models.Model):
    name = models.CharField(max_length=32)
    # other fields

class ItemRelation(models.Model):
    item = models.ForeignKey(Item, related_name='relations_item')
    user = models.ForeignKey(User, related_name='relations_user')
    has_viewed = models.BooleanField(default=False)
    has_loved = models.BooleanFields(default=False)

现在,我想做的是使用 django rest api.

获取所有项目的 view_count 和 love_count

views.py

class ItemView(ListAPIView):
    queryset = Items.objects.all().prefetch_related(Prefetch('relations_item',
            queryset=ItemRelation.objects.filter(Q(has_viewed=True) | Q(has_loved=True))
            )
    serializer_class = ItemSerializer

嗯,这是计划,但我完全不知道如何为列表-api-视图中的每个项目获取 view_count 和 love_count。我在我的序列化程序上尝试了很多东西,但我认为它不会起作用。 但是,我可以使用 SerializerMethod() 来完成这项工作,但这会通过 DB N+1 次。我已经通读了 prefetch_related 的文档和其他一些博客,并且在出现此计数问题之前我能够轻松地做事。

只是我的序列化程序中的一个示例。

class ItemSerializer(serializers.ModelSerializer):

    class Meta:
        model = Item
        fields = ['name', 'relations_item']

我想你想计算 a) has_viewed==True 和 b) has_loved==True.

的关系数

这应该可以通过使用 annotate()Django Conditional Expressions:

from django.db.models import Case, IntegerField, Sum, When


class ItemView(ListAPIView):
    queryset = Items.objects.annotate(
                   view_count=Sum(
                       When(relations_item__has_viewed=True, then=1),
                       output_field=IntegerField(),
                   ),
                   love_count=Sum(
                       When(relations_item__has_loved=True, then=1),
                       output_field=IntegerField(),
                   ),
               )
    # ...