Django 动态创建不相等的 q 个对象
Django dynamically create not equal q objects
我正在使用嵌套的 AND / OR 逻辑创建动态过滤器,并希望将 NOT 作为一个选项。这利用 Q 对象创建嵌套的 AND / OR 逻辑。
class 接收一个 json 对象,如下所示:
filters = {
'and': {
"url__is": "www.test.com",
"name__is": "test"
}
}
这被编译为
.filter(Q(url__is='www.test.com') and Q(name__is='test')
这是通过递归函数实现的,该函数实际上只是在 json 树的每个级别上执行此操作。
return source_queryset.filter(reduce(and_, filter_list))
and_ 来自 python 运算符库并且一直运行良好。不过,我也想添加 NOT 作为一个选项,但似乎找不到一个等效的选项来减少 Q 对象列表。
有谁知道以创建不等于 q 对象列表的方式使用 reduce 的方法吗?
您可以通过在其前面应用 ~
运算符来翻转任何 Q 对象。
.exclude(Q(id=5))
等同于:
.filter(~Q(id=5))
计算filter_list
时应该可以用到这个。
您正在 Q
对象上查找 ~
运算符,该对象是 complex lookup.
最后你会得到这样的结果:
.filter(~Q(url__is='www.test.com'))
要匹配您的递归函数,您应该使用 inv
or invert
运算符。因为它在使用 ~
运算符时匹配所需的输出。
>>> from django.db.models import Q
>>> from operator import inv
>>> ~Q()
<Q: (NOT (AND: ))>
>>> inv(Q())
<Q: (NOT (AND: ))>
所以你可以在你的递归函数中使用它,像这样:
return source_queryset.filter(map(inv, filter_list))
我正在使用嵌套的 AND / OR 逻辑创建动态过滤器,并希望将 NOT 作为一个选项。这利用 Q 对象创建嵌套的 AND / OR 逻辑。
class 接收一个 json 对象,如下所示:
filters = {
'and': {
"url__is": "www.test.com",
"name__is": "test"
}
}
这被编译为
.filter(Q(url__is='www.test.com') and Q(name__is='test')
这是通过递归函数实现的,该函数实际上只是在 json 树的每个级别上执行此操作。
return source_queryset.filter(reduce(and_, filter_list))
and_ 来自 python 运算符库并且一直运行良好。不过,我也想添加 NOT 作为一个选项,但似乎找不到一个等效的选项来减少 Q 对象列表。
有谁知道以创建不等于 q 对象列表的方式使用 reduce 的方法吗?
您可以通过在其前面应用 ~
运算符来翻转任何 Q 对象。
.exclude(Q(id=5))
等同于:
.filter(~Q(id=5))
计算filter_list
时应该可以用到这个。
您正在 Q
对象上查找 ~
运算符,该对象是 complex lookup.
最后你会得到这样的结果:
.filter(~Q(url__is='www.test.com'))
要匹配您的递归函数,您应该使用 inv
or invert
运算符。因为它在使用 ~
运算符时匹配所需的输出。
>>> from django.db.models import Q
>>> from operator import inv
>>> ~Q()
<Q: (NOT (AND: ))>
>>> inv(Q())
<Q: (NOT (AND: ))>
所以你可以在你的递归函数中使用它,像这样:
return source_queryset.filter(map(inv, filter_list))