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 只有具有多个身份的用户电子邮件身份。