【问题标题】:django order by aggregate value from non-related tabledjango 按非相关表中的汇总值排序
【发布时间】:2021-11-10 05:34:23
【问题描述】:

我有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'))

我想列出每个成员/司机的债务。可以通过@property 来完成;

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。我想按债务对每个成员进行排序。我该如何解决这个问题?

【问题讨论】:

    标签: django django-models django-rest-framework django-queryset django-orm


    【解决方案1】:

    您可以使用子查询添加基于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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多