【问题标题】:Django filtering using multiple queries使用多个查询的 Django 过滤
【发布时间】:2020-09-14 20:10:34
【问题描述】:

在我的主页上,我有一个搜索栏,当您搜索某些内容时,它会将您重定向到包含结果(标题和文档类型)的页面。在页面的左侧,我想按文档类型实现过滤器。

搜索后我的网址如下所示:http://127.0.0.1:8000/search/?q=something

应用过滤器后:http://127.0.0.1:8000/search/?document_type=Tehnical+report

我不知道如何实现过滤器以仅在搜索页面上由查询 (q) 过滤的对象列表中进行搜索。另外,我不确定应用过滤器后 url 是否应该是这样的:http://127.0.0.1:8000/search/?q=something&document_type=Tehnical+report 或这样的http://127.0.0.1:8000/search/?document_type=Tehnical+report

models.py

DOCUMENT_TYPES = [
    ('Tehnical report','Tehnical report'),
    ('Bachelor thesis','Bachelor thesis'),
    ...
]

class Form_Data(models.Model):
    title           = models.CharField(unique=True, max_length=100, blank=False)
    author          = models.CharField(max_length=100)
    document_type   = models.CharField(choices=DOCUMENT_TYPES, max_length=255, blank=False, default=None)

views.py

def search_list(request):
    object_list = Form_Data.objects.none()
    document_types = DOCUMENT_TYPES

    query = request.GET.get('q')
    query_list = re.split("\s|(?<!\d)[,.](?!\d)", query)
    document_type_query = request.GET.get('document_type')

    for item in query_list:
        object_list |= Form_Data.objects.filter( Q(title__icontains=item) | Q(author__icontains=item))

    return render(request, "Home_Page/search_results.html")

home_page.html

<div class="Search">
    <form action="{% url 'home_page:search_results' %}" method="get">
        <input id="Search_Bar" type="text" name="q">
        <button id="Button_Search" type="submit"></button>
    </form>
</div>

search_results.html

{% for form_data in object_list %}
    <h5>{{ form_data.title }}</h5>
    <h5>{{ form_data.document_type }}</h5>
{% endfor %}

<form method="GET" action=".">
    <select class="form-control" name="document_type">
        {% for tag, label in document_types %}
            <option value="{{ tag }}">{{ tag }}</option>
        {% endfor %}
    </select>
</form>

【问题讨论】:

    标签: python html django filter


    【解决方案1】:

    在我看来,你这样做是错误的......我的意思是我不明白你为什么要循环你的 query 进行过滤。据我所知,它正在循环您查询的每个字母。

    我正在这样做我会这样做(使用我自己的示例):

    <form action='{% url 'products:search' %}' method='get'>
        <input type='text' name='q' id='search' value='' >
        <select name='category' id='category'>
            <option value='' selected ></option>
            <option value='packet'>Packet</option>
            <option value='food'>Food</option>
            <option value='vegetable'>Vegetable</option>
        </select>
        <input type='button' value='submit' >
    </form>
    
    

    views.py:

    def search(request):
        products = None
        query = request.GET.get('q')
        category = request.GET.get('category')
        
        if query:
            products = Product.objects.filter(
                Q(name__icontains=query)|
                Q(brand__icontains=query)
            )
        if category:
            # since it is a choice field in the model
            products |= Products.objects.filter(category=category) 
    
        context = {
            'products': products,
        }
        return render(request, 'products/search_products.html', context)
    
    

    在这种情况下,如果我按下提交按钮,我会得到如下网址:

    http://localhost:8000/products/search/?q=something&amp;category=food

    使用这些数据,我可以按名称或我想要的任何其他字段过滤产品。

    我没有看到任何情况下有人会输入他们的查询并且搜索结果将包含在输入字段中输入任何字母的所有产品。

    【讨论】:

    • 我正在循环查询以进行过滤,因为用户可以搜索多个单词,并且我想显示匹配搜索句子中每个单词的结果。我有一个变量,它拆分输入以仅提取单词,但我忘了发布它。现在我更新了代码。我的问题是当我检查过滤器时,我没有初始查询的值(来自搜索栏),它显示了仅由 document_type 而不是查询“q”过滤的所有结果。如果无法保存“q”,如何检查这两个查询?
    • 我认为您的问题是您无法同时访问这两个过滤器。是不是因为它们的形式不同。我的意思是,如果你想在一个 GET 方法中传递多个字段,你必须将它们包含在同一个表单中,而不是不同的表单标签中。
    【解决方案2】:

    这将是模型过滤:

    query = request.GET.get('q')
    document_type_query = request.GET.get('document_type')
    
    object_list = FormData.objects.none()
    
    for item in query.split():
        item_qs = FormData.objects.filter(Q(title__icontains=item) | Q(author__icontains=item))
        if document_type_query:
             item_qs = item_qs.filter(document_type=document_type_query)
        object_list |= item_qs
    
    return render(request, "Home_Page/search_results.html", {"object_list": object_list})
    

    这是网址:

    http://127.0.0.1:8000/search/?q=something%20with%20spaces&document_type=Tehnical+report
    

    【讨论】:

    • 但是如果用户想要应用过滤器,我想搜索文档类型。默认情况下,它应该只显示由“q”查询搜索到的结果
    • 更新了我的答案@CătălinaSîrbu
    • 当我尝试这个时,我遇到了这个错误“预期的字符串或类似字节的对象”。我认为我的查询在使用一次后会被删除,我不知道如何保存它的值以便使用它。
    猜你喜欢
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 2020-04-16
    • 2018-08-04
    • 2017-03-28
    • 2016-11-07
    • 2015-02-17
    • 1970-01-01
    相关资源
    最近更新 更多