【问题标题】:Django: conditional expressionDjango:条件表达式
【发布时间】: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

这不会产生正确的结果。

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

【问题讨论】:

    标签: python django django-orm


    【解决方案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'
        )
    

    【讨论】:

      猜你喜欢
      • 2018-10-05
      • 2016-11-09
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多