【问题标题】:Change query string to allow for multiple values更改查询字符串以允许多个值
【发布时间】:2020-05-02 14:50:28
【问题描述】:

I have an issue with my query string, the problem is when multiple values are selected my Django search breaks.我在 URL ?Query=value1&Query=Value2 中得到了这个。在这种情况下,它只是搜索的最后一个值。我想要发生的是搜索这两个值(相当于AND 之间的运算符)。

这是想要的结果?Query=value1+Value2

我在下面添加了使用 Select2 和 Django 搜索视图的搜索表单。如果你现在还需要什么让我。

任何帮助将不胜感激。

前端搜索表单

<form id="makeitso" role="search" action="" method="get">                   
            <select class="js-example-placeholder-multiple" name="query" multiple="multiple">
                <option value="Value 1">Value 1</option>   
                <option value="Value 2">Value 2</option>   
                <option value="Value 3">Value 3</option>     
            </select>

               <script>
                   $(".js-example-placeholder-multiple").select2({
                       placeholder: "Search here",
                   });
               </script>

       <div class="form-inline justify-content-center">
           <button type="submit"  class="btn btn-xlarge">Search</button>
       </div>
   </form>

views.py

def search(request):
        search_query = request.GET.get('query', None)
        page = request.GET.get('page', 1)

        # Search
        if search_query:
            search_results = TestPage.objects.live().search(search_query)
            query = Query.get(search_query)

            # Record hit
            query.add_hit()
        else:
            search_results = TestPage.objects.none()

        # Pagination
        paginator = Paginator(search_results, 3)
        try:
            search_results = paginator.page(page)
        except PageNotAnInteger:
            search_results = paginator.page(1)
        except EmptyPage:
            search_results = paginator.page(paginator.num_pages)

        return render(request, 'search/search.html', {
            'search_query': search_query,
            'search_results': search_results,
        })

【问题讨论】:

标签: html django jquery-select2


【解决方案1】:

您需要使用GET 属性的getlist() 方法。

例如: search_query = request.GET.get('query', None)

应该是

search_query = request.GET.getlist('query', None)

然后您可以像这样遍历所有搜索查询:

for query in search_query:

然后您可以使用Q Objects 进行更复杂的查询:

q = Q()
for query in search_query:
    q |= Q(term=query)
ModelToQuery.objects.filter(q)

https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.QueryDict.getlist

https://docs.djangoproject.com/en/3.0/topics/db/queries/#complex-lookups-with-q-objects

【讨论】:

  • 感谢 Hybrid,我已经尝试过您的建议,但我收到属性错误“'list' object has no attribute 'lower'”。是否可以为我扩展您的答案?
  • 这不应该发生在你身上,除非你在返回的列表上调用 .lower() 或 .split()
  • 仍有问题。我发现我的多值查询只需将 & 替换为 + 即可。有没有一种简单的方法可以通过更新我的代码来做到这一点?
【解决方案2】:

感谢大家的建议,他们确实帮助了我,但我在下面制定的解决方案对于阅读此问题的任何人来说都是最有帮助的答案。下面的代码非常适合我的要求,并允许搜索多个值。

我能够使用 getlist 方法,然后使用带有 reduce 的 functools 模块(用于高阶函数)。该运算符允许andor,我目前正在使用and,它显示仅匹配所有搜索值的用户结果。

花了一段时间才到这里,希望这对其他人有帮助!

Views.py

def search(request):
    page = request.GET.get('page', 1)

    search_query = request.GET.getlist('query' , None)

    # searches for results that match all values
    query = functools.reduce(operator.and_, (Q(test_body__contains = i) for i in search_query))

    search_results = TestPage.objects.filter(query).distinct().order_by('-latest_revision_created_at') 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2011-04-18
    • 2015-02-26
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多