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

时间:2017-10-01 19:43:52

标签: django rest django-rest-framework foreign-keys reverse

我们说我有两个模特。

  

模型

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

嗯,这是计划,但我完全不知道如何获取list-api-view中每个项目的view_count和love_count。我在序列化器上尝试了很多东西,但我认为它不会起作用。 然而,我可以使用SerializerMethod()来完成工作,但这将经历DB N + 1次。我已经阅读了文档和其他一些prefetch_related的博客,我能够轻松地做这件事,直到出现这个计数问题。

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

class ItemSerializer(serializers.ModelSerializer):

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

1 个答案:

答案 0 :(得分:1)

我想你想计算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(),
                   ),
               )
    # ...