【问题标题】:Django - an equality check in annotate-clauseDjango - annotate-clause 中的相等检查
【发布时间】:2017-02-19 20:10:28
【问题描述】:

在我的 Django 1.9 项目中,我试图输出如下内容:

return MyModel.objects.values(...).\
               annotate(flg = ExpressionWrapper(F('rgt') - F('lft') > 0, 
                        output_field = BooleanField()))

这会产生AttributeError: 'bool' object has no attribute 'resolve_expression' 错误。

我尝试使用Case-when 语法重写它:

return MyModel.objects.values(...)\
              .annotate(flg = Case(When(F('rgt') - F('lft') > 0, then = True, 
               output_field = BooleanField())))

这一次,我遇到了TypeError: __init__() takes either a Q object or lookups as keyword arguments 错误。我搞不清楚了。有什么想法吗?

【问题讨论】:

    标签: django


    【解决方案1】:

    试试:

    return MyModel.objects.values(...).\
                   annotate(flg=ExpressionWrapper(Q(rgt=F('lft')), 
                            output_field=BooleanField()))
    

    功能请求使其更容易:https://code.djangoproject.com/ticket/27021

    【讨论】:

      【解决方案2】:

      Django 表达式不支持使用标准语法的比较运算符。

      查看https://docs.djangoproject.com/en/stable/ref/models/expressions/#supported-arithmetic

      但是,您可以使用Func() 表达式:https://docs.djangoproject.com/en/stable/ref/models/expressions/#func-expressions

      .annotate(flg=Func(F('rgt') + F('lft'), template='%(expressions)s > 0'))
      

      或者更好的是,定义一个 Function / Transform 类:

      class GreaterThanZero(Transform):
          template = '%(expressions)s > 0'
      
      .annotate(flg=GreaterThanZero(F('rgt') + F('lft')))
      

      转换是一元运算符,扩展Transform 可以确保只有一个expression 作为参数传递。所以你不能做GreaterThanZero(F('rgt') + F('lft'), 1, 2, 3, 14)

      显然,更灵活的解决方案应该允许通过比较的双方。像这样的东西:

      class GreaterThan(Func):
          arg_joiner = '<'
          arity = 2
          function = ''
      
      .annotate(flg=GreaterThan(F('rgt') + F('lft'), 0))
      

      【讨论】:

      • 如何比较字符串?
      • 这是一个功能请求code.djangoproject.com/ticket/27021,它有一个示例如何在实现之前实现它:Model.objects.annotate(boolfield=ExpressionWrapper(Q(field__gte=4), output_field=BooleanField()))
      猜你喜欢
      • 2017-12-26
      • 2019-01-15
      • 2011-05-02
      • 2021-01-30
      • 1970-01-01
      • 2015-08-11
      • 2015-10-17
      • 2011-04-23
      • 2020-04-15
      相关资源
      最近更新 更多