2017-02-19 55 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))