首页 > 解决方案 > Django 查询集搜索功能不起作用。返回未过滤的结果

问题描述

我正在尝试实现搜索功能,但是当我在搜索栏中输入查询时,它不会过滤任何内容并按原样返回所有内容,未经过滤。

论坛\views.py

def forum(request):
 context = {}

 # passing the query to the search bar
 query = ""
 if request.GET:
      query = request.GET['q']
      context['query'] = str(query)

 posts = sorted(get_forum_queryset(query), key=attrgetter('created_at'), reverse=True)

 return render(request, 'forum/discussion-forum.html')

def get_forum_queryset(query=None):
     queryset = []
     queries = query.split(" ")
     for  q in queries:
          posts = Post.objects.filter(
               Q(title__icontains=q) |
               Q(contents__icontains=q) |
               Q(tag__icontains=q)
          ).distinct()

          for post in posts:
               queryset.append(post)

     return list(set(queryset))

核心\模板\核心\base.html

<div class="search-bar">
  <form class="form-inline" method="GET">
    <div class="input-group">
      <div class="input-group-prepend">
        <span class="input-group-text"><i class='bx bx-search' ></i></span>
      </div>
      <input type="text" class="form-control" name="q" placeholder="Search" id="id_q">
    </div>
  </form>
</div>

为了将值设置为 {{query}} 到输入属性,我使用 javascript 设置了值,因为当我在 html 中这样做时它不起作用

<script type="text/javascript">
    document.getElementById("id_q").value = "{{query}}"
</script>

论坛\模板\论坛\讨论-forum.html

{% extends 'core/base.html' %}
{% block content %}

{% if posts %}
{% for post in posts %}
  # post the posts
{% endfor %}

{%else%}
<div class="container content-section">
  <div class="row">
    <div class="card m-auto">
      <div class="card-body mt-2 mb-2">
        <h2 class="card-title"> No results found </h2>
        <p class="card-body">
          Thre were no results matching your search: "{{query}}"
        </p>
      </div>
    </div>
  </div>
</div>

{% endif %}
{% endblock content %}

当我在搜索栏中输入内容并输入时,我的搜索栏会返回此内容。例如,我在这里输入了“python”。

http://localhost:8000/forum/discussion-forum/?q=python

我不知道可能出了什么问题。

标签: pythondjangosearchfilter

解决方案


你必须使用request.method == 'GET'- Django Docs

from django.db.models import Q
from django.shortcuts import render
import operator
from functools import reduce

def forum(request):
    context = {}

    # passing the query to the search bar
    query = ""
    if request.method == 'GET':
        query = request.GET.get("q", "")
        context['query'] = query
    queries = query.split(" ")
    context["posts"] = Post.objects.filter(reduce(operator.or_, (Q(title__icontains=x) | Q(contents__icontains=x) | Q(tag__icontains=x) for x in queries))).order_by('-created_at').distinct()

    return render(request, 'forum/discussion-forum.html', context)

您还可以使用reduceandoperator.or_过滤您的对象(参见上面的示例)。


推荐阅读