Django 注释模型并过滤特定值
Django annotate model and filter for specific value
我正在尝试使用 djangos annotate,但不太清楚它是如何工作的。
我有一个函数,我想在其中注释客户的查询集,过滤他们和 return 客户数量
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
是一个数据库字段
那么我如何注释查询集,过滤 received_signatures 然后 return 一个数字?
相关型号信息:
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) 仅在我的参与者处标记 brought_signature(这意味着他为他的所有注册带来了签名)或 B)在他的每个注册中标记 brought_signature
对于这种情况,选项 B) 是相关的。通过我的received_signatures
,我检查客户是否为他的状态为“1_YES”的每个注册带来了每个签名,我想计算所有这样做的客户和return一个数字(然后我将其用于 pygal 图表的另一个函数)
如果我理解正确,你想检查 all Registration
s 对于给定的 Customer
和 status == '1_YES
是否应该有作为属性.brought_signature = True
,至少应该有这样的值。有几种方法可以做到这一点。
我们可以这样写:
received_signatures = self.customer_set.filter(
registration__status='1_YES'
).annotate(
minb=Min('registration__brought_signature')
).filter(
minb__gt=0
).count()
所以我们在这里做的是首先 .filter(..)
在状态为 1_YES
的 registration
上,接下来我们为每个客户计算一个值 minb
即这些 Registration
中 brought_signature
的 最小值。因此,如果相关 Registration
的 brought_signature
之一是 False
(在通常为 0
的数据库中),则 Min(..)
是 False
还有。如果所有 brought_signature
都是 True
(在通常是 1
的数据库中),那么结果是 1
,然后我们可以过滤 [=18] =] 因此应该大于 0
.
所以 Customer
s with no Registration
will not, Customer
s没有 Registration
且状态为 1_YES
,将不被计算在内,Customer
和 Registration
有一个 Registration
且状态为 1_YES
, 但 brough_signature
将不被计算在内。只有 Customer
的 all Registration
具有状态 1_YES
(本身不是 all Registration
s) 有 brough_signature = True
被计算在内。
我正在尝试使用 djangos annotate,但不太清楚它是如何工作的。
我有一个函数,我想在其中注释客户的查询集,过滤他们和 return 客户数量
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
是一个数据库字段
那么我如何注释查询集,过滤 received_signatures 然后 return 一个数字?
相关型号信息:
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) 仅在我的参与者处标记 brought_signature(这意味着他为他的所有注册带来了签名)或 B)在他的每个注册中标记 brought_signature
对于这种情况,选项 B) 是相关的。通过我的received_signatures
,我检查客户是否为他的状态为“1_YES”的每个注册带来了每个签名,我想计算所有这样做的客户和return一个数字(然后我将其用于 pygal 图表的另一个函数)
如果我理解正确,你想检查 all Registration
s 对于给定的 Customer
和 status == '1_YES
是否应该有作为属性.brought_signature = True
,至少应该有这样的值。有几种方法可以做到这一点。
我们可以这样写:
received_signatures = self.customer_set.filter(
registration__status='1_YES'
).annotate(
minb=Min('registration__brought_signature')
).filter(
minb__gt=0
).count()
所以我们在这里做的是首先 .filter(..)
在状态为 1_YES
的 registration
上,接下来我们为每个客户计算一个值 minb
即这些 Registration
中 brought_signature
的 最小值。因此,如果相关 Registration
的 brought_signature
之一是 False
(在通常为 0
的数据库中),则 Min(..)
是 False
还有。如果所有 brought_signature
都是 True
(在通常是 1
的数据库中),那么结果是 1
,然后我们可以过滤 [=18] =] 因此应该大于 0
.
所以 Customer
s with no Registration
will not, Customer
s没有 Registration
且状态为 1_YES
,将不被计算在内,Customer
和 Registration
有一个 Registration
且状态为 1_YES
, 但 brough_signature
将不被计算在内。只有 Customer
的 all Registration
具有状态 1_YES
(本身不是 all Registration
s) 有 brough_signature = True
被计算在内。