如何通过某些属性用MAX注释相关对象

How to annotate related object with MAX by some attribute

class Bill(models.Model):
    number = CharField(max_length=32)

class Service(models.Model):
    number = CharField(max_length=32)
    bill = ForeignKey(Bill, related_name="bill_services")
    price = IntegerField()

bills = Bill.objects.prefetch_related('bill_services').annotate(service_number_with_max_price=....)

您好。我如何用每张账单的最高价格注释服务 number。 我想用它做类似的事情:

{% for bill in bills %}
    {{ bill.service_number_with_max_price }}
{% endfor %}

您可以使用聚合方法。

from django.db.models import Max

query = Bill.objects.all().prefetch_related("bill_services").aggregate(max_price=Max("bill_services__price"))

在模板中,您可以通过

获取服务的最高价格
{% for bill in bills %}
    {{ bill.max_price }}
{% endfor %}

您可以注释 subquery 来执行此操作:

from django.db.models import OuterRef, Subquery

subquery = Service.objects.filter(bill=OuterRef('pk')).order_by('-price').values('number')[:1]
bills = Bill.objects.prefetch_related('bill_services').annotate(service_number_with_max_price=Subquery(subquery))

子查询执行以下操作来实现您的用例:

  1. .filter(bill=OuterRef('pk')):获取Service个带外键的对象,外键查询当前行。
  2. .order_by('-price'): 按价格降序排列结果。
  3. .values('number'): Select 仅 number 字段。
  4. [:1]: 将子查询的结果限制在一行。