首页 > 解决方案 > 如何在模型中搜索多个类

问题描述

我有一个 django 项目,其中包括1 个模型文件,由 2 个类组成

请注意,这 2 个类不相关。

我有一个搜索表单,允许用户在这两个类中进行过滤。

基于这个问题的答案 Django search fields in multiple models

我使用了 itertools 和导入链

但我没有成功返回正确的结果。

根据@Willem Van Onsem 的回答更新代码

视图.py

class BaseSearchListView(ListView):
    context_object_name = 'result'
    # template_name = 'blog/update2.html'
    template_name = 'blog/list.html'



class FolderListView(BaseSearchListView):
    model = Folder

    def get_queryset(self, **kwargs):
        return super().get_queryset(**kwargs).filter(
            FolderNum__icontains= self.request.GET.get('q')
        )
        return render(self.request,"create_folder_test.html",{'search-folder':to_search})

class SuspectListView(BaseSearchListView):
    model = suspect

    def get_queryset(self, **kwargs):
        query = self.request.GET.get('q')
        return super().get_queryset(**kwargs).filter(
            Q(suspect_name__icontains=query) |
            Q(suspect_father_name__icontains=query) |
            Q(suspect_mother_name__icontains=query) |
            Q(content__icontains=query) |
            Q(create_date__icontains=query)
        ).distinct()

        #paginator in order to make several pages 
        paginator = Paginator(queryset_list, 10) # Show 5 items per page
        page_request_var = "page"#this line to change dynamicly the string befor the number of page like **page 1** or **abc 1**
        page = request.GET.get(page_request_var)
        queryset = paginator.get_page(page)

        context={
            "object_list":queryset,
            "title":"List Items",
            "page_request_var":page_request_var,
        }
        return render(self.request ,"blog/list.html",{'search-suspect':to_search})

header.html

<body>

<div class="mynav">
    <nav class="navbar  navbar-expand-sm bg-light navbar-light ">
        <ul class="navbar-nav mr-auto ">
               <li class="nav-item ">
                 <a class="nav-link" href="{%  url 'create_folder_test'  %}">MainPage</a>
            </li>
        </ul>
        <ul class="navbar-nav ">

                <input type="text" class="form-control" placeholder="Search this blog">
                    <div class="input-group-append">
                        <button class="btn btn-secondary" type="button">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>
            </div>
        <form class="form-inline" method="GET" action="{% url to_search|default:'search-folder' %}">
                <input class="form-control mr-sm-2" type="text" placeholder="search..." name="q" value="{{request.GET.q}}">

                    <button class="btn btn-secondary" type="submit">

                    </button>

            </form>             
        </ul>
    </nav>

标签: djangodjango-modelsitertools

解决方案


Achain是一个惰性迭代器。如果你打印它,你就打印了这个chain对象。

在您的模板中,您应该遍历链对象,例如:

{% for item in result %}
    {{ item }}
{% endfor %}

在您看来,您可以打印对象列表,例如通过首先构造一个列表:

    print([*folders, *suspects])

编辑

如果您只想显示两个结果之一,我建议您制作两个单独的视图。也许作为一个子类ListView

# app/views.py

from app.models import Folder, Suspect

from django.db.models import Q
from django.views.generic.list import ListView

class BaseSearchListView(ListView):
    context_object_name = 'result'
    template_name = 'blog/update2.html'


class FolderListView(BaseSearchListView):
    model = Folder

    def get_queryset(self, **kwargs):
        return super().get_queryset(**kwargs).filter(
            FolderNum__icontains= self.request.GET.get('q'))
        )

class SuspectListView(BaseSearchListView):
    model = suspect

    def get_queryset(self, **kwargs):
        query = self.request.GET.get('q')
        return super().get_queryset(**kwargs).filter(
            Q(suspect_name__icontains=query) |
            Q(suspect_father_name__icontains=query) |
            Q(suspect_mother_name__icontains=query) |
            Q(content__icontains=query) |
            Q(create_date__icontains=query)
        ).distinct()

然后urls.py可以使用两个视图:

# app/urls.py

from django.urls import include, path
from app import views

urlpatterns = [
    path('search_folder/', views.FolderListView.as_view(), name='search-folder'),
    path('search_suspect/', views.SuspectListView.as_view(), name='search-suspect')
]

然后你可以写一个表格:

<form class="form-inline" method="GET" action="{% url to_search|default:'search-folder' %}">
    <!-- ... -->
</form>

现在,您可以在渲染模板的上下文中设置一个变量,以更改操作目标。例如,如果您传递给 context {'to_search': 'search-suspect'},它将因此指向不同的视图。


推荐阅读