【问题标题】:Group By in Django ORM?在 Django ORM 中分组?
【发布时间】:2020-07-21 16:46:56
【问题描述】:

我有两个模型

class ShareType(models.Model):
    code = models.CharField(max_length=10, null=False, blank=False)
    type = models.CharField(max_length=56, null=False, blank=False)

class ShareAllocation(models.Model):
    session_key = models.CharField(max_length=40, null=True)
    share_type = models.ForeignKey(ShareType, on_delete=models.CASCADE, null=True)
    share_holder = models.ForeignKey(ShareHolder, on_delete=models.CASCADE, null=True)
    number_of_shares = models.IntegerField(null=False, blank=False)
    amount_paid = models.IntegerField(null=False, blank=False)
    amount_unpaid = models.IntegerField(null=False, blank=False)
    is_beneficial_owner = models.BooleanField(null=False, blank=False)

我正在使用这个查询,这显然是不正确的。

share_structure = ShareType.objects.annotate(Sum('shareallocation__number_of_shares')).\
                filter(shareallocation__session_key=self.storage.request.session.session_key)

共享分配表的样本数据

12,5,2,1,false,9,9,098fiy6m9f0tkkmnk8jr715pyjlzcai6
13,10,2,1,false,10,12,098fiy6m9f0tkkmnk8jr715pyjlzcai6
14,15,2,1,false,12,12,098fiy6m9f0tkkmnk8jr715pyjlzcai6

共享类型表的示例数据

9,ORD,(ORD) Ordinary 
10,A,(A) A 
11,B,(B) B 
12,MAN,(MAN) Management 
13,LG,(LG) Life Governors 
14,EMP,(EMP) Employees 
15,FOU,(FOU) Founders 
16,PRF,(PRF) Preference 
17,CUMP,(CUMP) Cumulative Preference 
18,NCP,(NCP) Non Cumulative Preference 
19,REDP,(REDP) Redeemable Preference 
20,NRP,(NRP) Non Redeemable Preference 
21,NCRP,(NCRP) Non Cum. Redeemable Preference 
22,PARP,(PARP) Participative Preference 
23,RED,(RED) Redeemable 
24,INI,(INI) Initial 
25,SPE,(SPE) Special  

需要的输出:

  • 代码
  • 股份数量(总数)
  • 支付金额(总计)
  • 未付金额(总计)

【问题讨论】:

  • 请分享示例数据、所需输出和您当前的输出。
  • 在原始帖子中添加数据和输出

标签: python django django-orm


【解决方案1】:

一种更简洁的方法是在您的 ShareType 模型中放置一个函数,用于显示股份数量、已付金额和未付金额

from django.db.models import Sum

class ShareType(models.Model):
    code = models.CharField(max_length=10, null=False, blank=False)
    type = models.CharField(max_length=56, null=False, blank=False)

    def number_of_shares(self):
        return ShareAllocation.objects.filter(share_type = self).count()
    
    def amount_paid(self):
        return ShareAllocation.objects.filter(share_type = self).aggregate(Sum('amount_paid'))

    def amount_unpaid(self):
        return ShareAllocation.objects.filter(share_type = self).aggregate(Sum('amount_unpaid')) 

class ShareAllocation(models.Model):
    session_key = models.CharField(max_length=40, null=True)
    share_type = models.ForeignKey(ShareType, on_delete=models.CASCADE, null=True)
    share_holder = models.ForeignKey(ShareHolder, on_delete=models.CASCADE, null=True)
    number_of_shares = models.IntegerField(null=False, blank=False)
    amount_paid = models.IntegerField(null=False, blank=False)
    amount_unpaid = models.IntegerField(null=False, blank=False)
    is_beneficial_owner = models.BooleanField(null=False, blank=False)

然后您可以像读取字段一样读取这些值

【讨论】:

  • 我也尝试了一些东西,但并没有真正到达那里,share_structure = ShareAllocation.objects.\ values('share_type__code','number_of_shares').\ filter(session_key=self.storage.request.session.session_key).\ annotate(Count('share_type__code')).\ annotate(Sum('number_of_shares'))
  • 试试这个 share_structure = ShareAllocation.objects.filter(session_key=self.storage.request.session.session_key).annotate(number_shares=Count('sharetype')).annotate(amount_paid=Sum(' sharetype__amount_paid'))
【解决方案2】:

我认为这就是所谓的改变!我有一种感觉,我会看到很多……除了

解决办法

    share_structure = ShareAllocation.objects.values('share_type__code','share_type__type').\
        annotate(share_count=Sum('share_type')). \
        annotate(number_of_shares=Sum('number_of_shares')).\
        annotate(amount_paid=Sum('amount_paid')).\
        annotate(amount_unpaid=Sum('amount_unpaid'))

挑战在于理解或不理解我的所有列名都来自值​​字段。

从本练习中学到的主要知识表明,引用表的列将以 tablename__filedname 的形式出现 和汇总的列将来自注释函数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 2017-03-30
    • 1970-01-01
    • 2012-04-26
    • 2018-03-10
    • 2018-01-03
    • 1970-01-01
    相关资源
    最近更新 更多