Django:条件表达式

Posted

技术标签:

【中文标题】Django:条件表达式【英文标题】:Django: conditional expression 【发布时间】:2016-07-08 08:16:41 【问题描述】:

我有以下型号:

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

这不会产生正确的结果。

任何帮助将不胜感激。提前致谢。

【问题讨论】:

【参考方案1】:

我想你想在这里使用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.core.exceptions.FieldError: Cannot resolve expression type, unknown output_field 你知道这是什么意思吗? 看起来你必须告诉Case它是什么类型的字段,我已经编辑了答案 如dm295的回答中提到的,then=Value(True)需要用When()-docs.djangoproject.com/en/2.0/ref/models/…传入【参考方案2】:

接受的答案不适用于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'
    )

【讨论】:

以上是关于Django:条件表达式的主要内容,如果未能解决你的问题,请参考以下文章

使用“OR”条件的正则表达式

条件语句

第5节条件运算符和条件表达式学习导案

第5节条件运算符和条件表达式学习导案

第5节条件运算符和条件表达式学习导案

C语言条件表达式