2017-02-19 59 views
1

相等性检查在我的Django 1.9的项目,我想输出是这样的:Django的 - 在注释子句

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错误。我搞不清楚了。有任何想法吗 ?

回答

1

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

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

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

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

甚至更​​好,定义一个函数/ 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)

显然,一个更灵活的解决方案应该允许通过比较的双方。 Somethin like this:

class GreaterThan(Func): 
    arg_joiner = '<' 
    arity = 2 
    function = '' 

.annotate(flg=GreaterThan(F('rgt') + F('lft'), 0))