Django:条件表达式

Django: conditional expression

我有以下型号:

class Agreement(models.Model):
    ...
    organization = models.ForeignKey("Organization")

class Signed_Agreement(models.Model):
    agreement = models.ForeignKey("Agreement")
    member = models.ForeignKey("Member")

我想做的是获取特定组织 (self.organization) 的所有协议的列表,并用有关它是否已由特定成员签署的信息注释每个协议 ( self.member).

如果已签署协议,则存在特定协议和成员的 Signed_Agreement 实例。

如何为此编写查询?

这是我到目前为止的努力:

from django.db.models import When, F, Q, Value

def get_queryset(self):

    agreements = _agreement_model.Agreement.objects.filter(
        organization=self.organization
    ).annotate(
        signed=When(Q(signed_agreement__member=self.member), then=Value(True))
    ).order_by(
        'name'
    )

    return agreements

这没有产生正确的结果。

如有任何帮助,我们将不胜感激。提前致谢。

我想你想在这里使用 Case

def get_queryset(self):

    agreements = _agreement_model.Agreement.objects.filter(
        organization=self.organization
    ).annotate(
        signed=Case(When(signed_agreement__member=F('member')),
                    then=Value(True),
                    default=Value(False),
                    output_field=BooleanField()
    ).order_by(
        'name'
    )

    return agreements

更新

根据评论,似乎在更高版本的 Django 中 then 必须在 When

中传递
def get_queryset(self):

    agreements = _agreement_model.Agreement.objects.filter(
        organization=self.organization
    ).annotate(
        signed=Case(When(signed_agreement__member=F('member'), 
                         then=Value(True)
                    ),
                    default=Value(False),
                    output_field=BooleanField()
    ).order_by(
        'name'
    )

    return agreements

已接受的答案不适用于 Django 1.11.6。我必须输入 then inside When 才能使其正常工作。

from django.db.models import Case, When, F, BooleanField


def get_queryset(self):
    agreements = _agreement_model.Agreement.objects.filter(
        organization=self.organization
    ).annotate(
        signed=Case(
            When(
                signed_agreement__member=F('member'),
                then=True
            ),
            default=False,
            output_field=BooleanField()
        )
    ).order_by(
        'name'
    )