Django -注解子句中的相等性检查

smdncfj3  于 2023-02-05  发布在  Go
关注(0)|答案(3)|浏览(102)

在我的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错误结束。我迷路了。有什么想法吗?

34gzjxbg

34gzjxbg1#

试试看:

from django.db.models import Q, F

...

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

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

z9smfwbn

z9smfwbn2#

Django表达式不支持使用标准语法的比较操作符。
查看www.example.comhttps://docs.djangoproject.com/en/stable/ref/models/expressions/#supported-arithmetic
但是,可以使用Func()表达式:www.example.comhttps://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))
ukxgm1gy

ukxgm1gy3#

从“Django 4.0”开始你就可以做到了

from django.db.models import F
from django.db.models.lookups import Exact

queryset.annotate(is_current=Exact(
    F('id'), F('user__account__current_subscription')
))

Django commit with examples and testcases

相关问题