【问题标题】:Django annotate model and filter for specific valueDjango注释模型并过滤特定值
【发布时间】:2019-01-13 11:19:55
【问题描述】:

我正在尝试使用 djangos annotate,但不能完全弄清楚它是如何工作的。

我有一个函数,我想在其中注释客户查询集,过滤它们并返回客户数量

def my_func(self):
    received_signatures = self.customer_set.annotate(Count('registrations').filter().count()

现在对于过滤器部分,这就是我在弄清楚如何做到这一点时遇到的问题。我要过滤的是我的received_signatures,这是一个在我的 customer.py 中调用的函数

def received_signatures(self):
    signatures = [reg.brought_signature for reg in self.registrations.all() if reg.status == '1_YES']
    if len(signatures): 
        return all(signatures)
    else:
       return None

brough_signature 是一个数据库字段

那么我怎样才能注释查询集,过滤收到的签名,然后返回一个数字?

相关型号信息:

class Customer(models.Model):
    brought_signature = models.BooleanField(u'Brought Signature', default=False)


class Registration(models.Model):
    brought_signature = models.BooleanField(u'Brought Signature', default=False)
    status = models.CharField(u'Status', max_length=10, choices=STATUS_CHOICES, default='4_RECEIVED')

注意:参与者和注册可以有brought_signature。我在我的程序中有一个设置,允许我 A)仅在我的参与者处标记bred_signature(这意味着他为他的所有注册都带来了签名)或 B)为他的每个注册标记bred_signature

对于这种情况,选项 B) 是相关的。使用我的received_signatures,我检查客户是否为他的状态为“1_YES”的每个注册带来了每个签名,我想计算所有这样做的客户并返回一个数字(然后我在另一个函数中使用 pygal图表)

【问题讨论】:

  • 但是如果你统计Customers的数量,那么先注释这些有什么用呢?
  • 如果我理解正确,你想Count 至少有一个Registration 的Customers 的数量,其中status == '1_YES' 对,并检查是否都有brough_signature = 1 ?
  • 是否可以 (a) 共享模型的(相关)部分,以及 (b) 描述您想要的什么,而不是如何去做(XY 问题)。
  • @WillemVanOnsem 没错,计算每个客户至少有一次注册,其中状态为 1_YES,如果他们带来了所有签名(有些客户可以有多个签名)我会更新我的问题
  • @WillemVanOnsem 我添加了更多信息,希望现在可以更好地理解

标签: python django django-annotate


【解决方案1】:

如果我理解正确,您想检查 all 给定 Customer 和 status == '1_YES 的 Registrations 是否应该具有属性 .brought_signature = True,并且应该有 至少这样的价值。有几种方法可以做到这一点。

我们可以这样写:

received_signatures = self.customer_set.filter(
    registration__status='1_YES'
).annotate(
    minb=Min('registration__brought_signature')
).filter(
    minb__gt=0
).count()

所以我们在这里要做的首先是registrations 上的.filter(..),其状态为1_YES,接下来我们为每个客户计算一个值minb,它是最小值 brought_signature 这些Registrations。因此,如果相关Registrations 的brought_signatures 之一是False(在通常为0 的数据库中),那么Min(..) 也是False。如果所有brought_signatures 都是True(在通常是1 的数据库中),那么结果是1,然后我们可以过滤minb 应该大于0 的事实.

所以Customers 与 no Registration 将不计入,Customers 没有Registration 与状态1_YES 将不计入计算,Customers 和 Registrations 有一个 Registration 和状态 1_YES,但 brough_signature 不会被计算在内。只有Customers 具有1_YES 状态的所有 Registrations(不是本身所有 Registrations)具有brough_signature = True 的brough_signature = True。

【讨论】:

    猜你喜欢
    • 2019-08-17
    • 2018-02-22
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    相关资源
    最近更新 更多