You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django ORM如何为Bill对象注解关联的最高价Service的number属性

实现方式

你可以通过两种常用方案实现需求:


方案1:ORM子查询注解(数据库层完成计算)

这种方式直接在查询数据库时就完成注解,不需要额外处理关联数据,性能更优,适合不需要拉取当前Bill下所有Service的场景。

首先导入需要的ORM工具:

from django.db.models import OuterRef, Subquery

构造子查询筛选每个Bill下价格最高的Service的number字段:

# 子查询逻辑:匹配外层Bill的主键,按价格倒序取第一条的number
max_price_service = Service.objects.filter(
    bill=OuterRef('pk')
).order_by('-price').values('number')[:1]

最终的查询语句如下,你原来写的prefetch_related如果没有其他用途可以去掉,不影响注解结果:

bills = Bill.objects.annotate(
    service_number_with_max_price=Subquery(max_price_service)
).all()

方案2:模型属性实现(适合已预取关联Service的场景)

如果你已经需要预取当前Bill下的所有Service做其他业务处理,可以直接在Bill模型中新增属性实现,逻辑更直观:

class Bill(models.Model):
    number = CharField(max_length=32)
    
    @property
    def service_number_with_max_price(self):
        # 直接使用prefetch好的关联数据,不会产生额外查询
        top_service = self.bill_services.order_by('-price').first()
        return top_service.number if top_service else ''

注意:使用这个方案必须搭配prefetch_related('bill_services'),否则会产生N+1查询问题。

两种方案都支持你在模板中直接用{{ bill.service_number_with_max_price }}调用取值。


内容的提问来源于stack exchange,提问作者Rey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:18:01