动态组合 Q() - OR 对象

Posted

技术标签:

【中文标题】动态组合 Q() - OR 对象【英文标题】:Dynamically combine Q() - OR objects 【发布时间】:2018-08-18 05:14:21 【问题描述】:

我正在尝试在我拥有的这个 ListView 中创建一个动态搜索。我的想法是在每次尝试继承此视图时指定搜索的字段和类型。

我的问题是每次我尝试进行搜索时,它只适用于元组的第一个字段。在我的示例中:requests__email 是第一个字段,当我在查询“app”后打印对象 query_q 时,我得到以下输出:

(OR: (AND: ), ('requests__email__icontains', 'app'), (AND: ('requests__email__icontains', 'app'), ('status__icontains', 'app')), (AND: ('requests__email__icontains', 'app'), ('status__icontains', 'app'), ('license_type__name__icontains', 'app')))

我不明白为什么,因为我使用的运算符我认为它可以在query_q |= Q(**query_kwargs) 中工作|=。如果我尝试根据其他属性进行搜索,例如status,搜索将不起作用。

views.py

class DefaultListView(ListView):
    searchable_fields = (
        ('requests__email', 'icontains'),
        ('status', 'icontains'),
        ('license_type__name', 'icontains'),
    )

    def get_queryset(self):
        form = self.form_class(self.request.GET)

        if form.is_valid():
            if not self.searchable_fields:
                raise AttributeError('searchable_fields has not been configured.')
            term = form.cleaned_data['term']
            query_kwargs = dict()
            query_q = Q()

            # Build a list of Q objects based on the searchable attribute
            for field, search_type in self.searchable_fields:
                query_kwargs["0__1".format(field, search_type)] = term
                query_q |= Q(**query_kwargs)

            ordering = self.get_ordering()
            queryset = self.model.objects.filter(query_q)

            if ordering:
                return queryset.order_by(**ordering)

            return queryset
        return super(DefaultListView, self).get_queryset()

【问题讨论】:

【参考方案1】:

如果您想将查询构建为 X = Y OR W = Z 这是因为

query_kwargs["0__1".format(field, search_type)] = term

您在循环的每次迭代中向query_kwargs 添加更多键,而不是重新创建变量 会建议这样的东西

for field, search_type in self.searchable_fields:
    query_q |= Q(**"0__1".format(field, search_type): term)

【讨论】:

啊啊啊。非常真实。完全没注意那个。感谢您强调它。 :)

以上是关于动态组合 Q() - OR 对象的主要内容,如果未能解决你的问题,请参考以下文章

Django:使用 Q 对象对任意数量的输入进行动态过滤(OR & AND)

Django SQL OR via filter() & Q(): 动态?

Django - 将列表转换为 Q 对象的组合 OR 的正确方法 [重复]

如何从字符串内的括号中使用 Django Q 对象创建动态查询

如何在 Play Morphia 中动态组合 OR 查询中的多个条件

thinkphp 区间查询 组合查询 复合查询 动态查询 SQL查询