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))