Django 查询注释匹配特定值的外键数量
Django query to annotate number of foreign keys matching certain value
如果我有以下相关机型:
class User(models.Model):
...
class Identity(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
category = models.CharField(max_length=8, choices=IDENTITY_CATEGORIES)
...
我如何查询具有多个 电子邮件 身份的用户,其中存在类别 "email" 的多个 Identity
实例指向相同的 [=12] =].
我看过 Django 1.8 introduced Conditional Expressions,但我不确定它们如何适用于这种情况。
通过应用 django.db.models.Sum
,这是实现它的一种方法:
from django.db.models import Case, IntegerField, Sum, When
def users_with_multiple_email_identities():
"""
Return a queryset of Users who have multiple email identities.
"""
return (
User.objects
.annotate(
num_email_identities=Sum(
Case(
When(identity__category='email', then=1),
output_field=IntegerField(),
default=Value(0)
)
)
)
.filter(num_email_identities__gt=1)
)
因此,我们使用 .annotate()
创建一个聚合字段来表示每个用户的电子邮件身份数量,然后将 .filter()
应用于结果 return 只有具有多个身份的用户电子邮件身份。
如果我有以下相关机型:
class User(models.Model):
...
class Identity(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
category = models.CharField(max_length=8, choices=IDENTITY_CATEGORIES)
...
我如何查询具有多个 电子邮件 身份的用户,其中存在类别 "email" 的多个 Identity
实例指向相同的 [=12] =].
我看过 Django 1.8 introduced Conditional Expressions,但我不确定它们如何适用于这种情况。
通过应用 django.db.models.Sum
,这是实现它的一种方法:
from django.db.models import Case, IntegerField, Sum, When
def users_with_multiple_email_identities():
"""
Return a queryset of Users who have multiple email identities.
"""
return (
User.objects
.annotate(
num_email_identities=Sum(
Case(
When(identity__category='email', then=1),
output_field=IntegerField(),
default=Value(0)
)
)
)
.filter(num_email_identities__gt=1)
)
因此,我们使用 .annotate()
创建一个聚合字段来表示每个用户的电子邮件身份数量,然后将 .filter()
应用于结果 return 只有具有多个身份的用户电子邮件身份。