Django OR 使用基于字典的过滤器进行搜索

Posted

技术标签:

【中文标题】Django OR 使用基于字典的过滤器进行搜索【英文标题】:Django OR search with dictionary-based filter 【发布时间】:2020-10-28 01:07:33 【问题描述】:

已编辑以阐明所需的结构。

我正在研究其他人的代码,并希望修改搜索行为 - 以便将查询输入用作跨两个字段的“或”查询。

目前我有这个:

forms.py

class SearchForm(forms.Form):
    area = forms.ModelChoiceField(label=_('Area'), queryset=Area.objects.all(), required=False)
    group = forms.ModelChoiceField(label=_('Group'), queryset=Group.objects.all(), required=False)
    q = forms.CharField(required=False, label=_('Query'),)

    def filter_by(self):
        # TODO search using more than one field
        # TODO split query string and make seaprate search by words
        filters = 
        if self.cleaned_data['group']:
            filters['group'] = self.cleaned_data['group']

        if self.cleaned_data['area']:
            filters['area'] = self.cleaned_data['area']

        filters['description__icontains'] = self.cleaned_data['q']
        #filters['title__icontains'] = self.cleaned_data['q']

        return filters

views.py

class FilteredListView(FormMixin, ListView):
    def get_form_kwargs(self):
        return 
            'initial': self.get_initial(),
            'prefix': self.get_prefix(),
            'data': self.request.GET or None
        

    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()

        form = self.get_form(self.get_form_class())

        if form.is_valid():
            self.object_list = self.object_list.filter(**form.filter_by())

        context = self.get_context_data(form=form)
        return self.render_to_response(context)

我想做的是接受“q”输入并执行以下操作:

self.object_list.filter(Q(title__icontains = request.GET['q']) | Q(description__icontains = request.GET['q']))

因此,在“标题”或“描述”中出现“q”的地方返回结果,或两者兼而有之。但是我无法找到一种方法来通过 filter_by 返回当前的字典。

用 SQL 术语来说,结束查询应该如下所示:

…'group' = 1 AND 'area' = 2 AND 
   ('title' LIKE \'%stack%\' OR 'description' LIKE  \'%stack%\')…

而不是全部是“AND”或“OR”,即能够混合运算符。在这种情况下,是的,“标题”或“描述”具有相同的查询输入。

可以这样做吗?我只想尽可能轻松地更新代码,而不需要重新编写整个代码。

轻触要求的原因是,如果从表面上看,它只是对现有代码的一小部分补充,则更有可能被审查和接受为拉取请求。

谢谢。

【问题讨论】:

【参考方案1】:
if form.is_valid():
    self.object_list = self.object_list.filter(
        area=form.filter_by()['area'], group=form.filter_by()['group'],
        (Q(title__icontains = request.GET['q']) | Q(description__icontains = request.GET['q']))
    )        

【讨论】:

关于过滤器链接性能的一些很好的讨论:***.com/questions/8164675/…

以上是关于Django OR 使用基于字典的过滤器进行搜索的主要内容,如果未能解决你的问题,请参考以下文章

使用过滤器时如何使用 django_tables2 进行搜索

我想在 Django 中进行两个查询集搜索

Django 模板中的日期/时间格式

如何在 django 中进行复杂的搜索?使用视图还是模型?

获取过滤值的字典键

在 Django 模板中,如何指定本身就是属性的字典键?