【问题标题】:Can I annotate onto a select_related() field?我可以在 select_related() 字段上进行注释吗?
【发布时间】:2020-12-15 12:03:27
【问题描述】:

我想注释每个车主拥有多少辆汽车作为优化。

这似乎是一种奇怪的方法,但我使用的是 Django Rest Framework,序列化的 Car 有一个 Owner 字段,而Owner 序列化包含动态计算的汽车数量用户拥有。

这是我想要的某种...

cars = Car.objects.select_related('owner').annotate(owner__cars_count=Count('owner__car'))

...除了我想要的是cars[0].owner.cars_count 而不是cars[0].owner__cars_count。我想注释 owner,而不是 car,以便 DRF 在序列化所有者时具有可用的字段。

objects 换成Owner 也不行,因为select_related 不适用Car 不使用Owner 管理器。

这与Nested annotate fields in Django REST Framework serializers 非常相似,但接受的答案是我已经在做的——计算SerializerMethodField 中的每条记录。一个不被接受的答案描述了使用prefetch_related 而不是select_related

由于这是 DRF,或者我可以在注释到达嵌套序列化程序之前将其从 Car.owner__cars_count 复制到 Car.owner.cars_count

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    你可以使用 Prefetch 类:

    from django.db.models import Count, Prefetch
    
    cars = Car.objects.prefetch_related(Prefetch('owner', Owner.objects.annotate(cars_count=Count('car'))))
    
    for car in cars:
        print(car.owner.cars_count)
    

    【讨论】:

    • 这很有趣。我没有意识到你可以prefetch 一个外键——我认为它适用于许多关系。 prefetch_related('owner') 以两个查询结束,但它仍然比替代方案更好。
    猜你喜欢
    • 2019-07-21
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 2016-10-17
    • 2020-09-20
    相关资源
    最近更新 更多