django 按非相关聚合值排序 table
django order by aggregate value from non-related table
我有三个模型,Accrual和Member,这两个模型的公共字段是register_no,但是这个字段不是外键
class Accrual(models.Model):
register_no = models.PositiveIntegerField(verbose_name=_('Register No'))
amount=models.DecimalField(decimal_places=2, max_digits=17, verbose_name=_('Total Amount'))
class Member(models.Model):
register_no = models.PositiveIntegerField(unique=True, verbose_name=_('Register No'))
class Driver(models.Model):
register_no = models.PositiveIntegerField(unique=True, verbose_name=_('Register No'))
我想列出每个 member/driver 的债务。可以用@属性;
来完成
class Member(models.Model):
register_no = models.PositiveIntegerField(unique=True, verbose_name=_('Register No'))
@property
def debt(self):
ret_val = Accrual.objects.filter(register_no=self.register_no).aggregate(
debt=Sum('amount'))
debt = ret_val.get('debt', 0)
return debt if debt else 0
但我不能这样使用 order_by。我想按债务对每个成员进行排序。我该如何解决这个问题?
您可以使用子查询添加所有基于 register_no
:
的相关应计项目
from django.db.models import OuterRef, Subquery, Sum
accruals = Accrual.objects.filter(
register_no=OuterRef('register_no')
).values('register_no').annotate(debt=Sum('amount'))
Member.objects.annotate(
debt=Subquery(accruals.values('debt'))
).order_by('debt')
产生这个 sql:
SELECT "id", "register_no", (
SELECT SUM(U0."amount") AS "debt"
FROM "accrual" U0
WHERE U0."register_no" = ("register_no")
GROUP BY U0."register_no"
) AS "debt"
FROM "member"
ORDER BY "debt" ASC
我有三个模型,Accrual和Member,这两个模型的公共字段是register_no,但是这个字段不是外键
class Accrual(models.Model):
register_no = models.PositiveIntegerField(verbose_name=_('Register No'))
amount=models.DecimalField(decimal_places=2, max_digits=17, verbose_name=_('Total Amount'))
class Member(models.Model):
register_no = models.PositiveIntegerField(unique=True, verbose_name=_('Register No'))
class Driver(models.Model):
register_no = models.PositiveIntegerField(unique=True, verbose_name=_('Register No'))
我想列出每个 member/driver 的债务。可以用@属性;
来完成class Member(models.Model):
register_no = models.PositiveIntegerField(unique=True, verbose_name=_('Register No'))
@property
def debt(self):
ret_val = Accrual.objects.filter(register_no=self.register_no).aggregate(
debt=Sum('amount'))
debt = ret_val.get('debt', 0)
return debt if debt else 0
但我不能这样使用 order_by。我想按债务对每个成员进行排序。我该如何解决这个问题?
您可以使用子查询添加所有基于 register_no
:
from django.db.models import OuterRef, Subquery, Sum
accruals = Accrual.objects.filter(
register_no=OuterRef('register_no')
).values('register_no').annotate(debt=Sum('amount'))
Member.objects.annotate(
debt=Subquery(accruals.values('debt'))
).order_by('debt')
产生这个 sql:
SELECT "id", "register_no", (
SELECT SUM(U0."amount") AS "debt"
FROM "accrual" U0
WHERE U0."register_no" = ("register_no")
GROUP BY U0."register_no"
) AS "debt"
FROM "member"
ORDER BY "debt" ASC