【问题标题】:Django Mixins Search FunctionDjango Mixins 搜索功能
【发布时间】:2015-10-01 04:22:13
【问题描述】:

我有一个工作正常的 FBV 搜索功能,如下所示:

def search(request):
    query_string = ''
    found_entries = None
    if ('q' in request.GET) and request.GET['q'].strip():
        query_string = request.GET['q']

        entry_query_study = get_query(query_string, ['title', 'category', 'service', 'subject', 'industry', 'description', 'keywords', 'objective',])
        entry_query_page = get_query(query_string, ['title', 'url', 'category', 'keywords',])

        found_entries_study = Study.objects.filter(entry_query_study).order_by('title')
        found_entries_page = Page.objects.filter(entry_query_page).order_by('title')

        found_entries = list(chain(found_entries_page, found_entries_study))

    return render_to_response('search-results.html',
                         { 'query_string': query_string, 'found_entries': found_entries },
                          context_instance=RequestContext(request))

我有一个不起作用的 CBV 搜索功能,其中包含如下所示的 mixin:

class SearchMixin(object):
    def get_queryset(self):
        query_string = ''
        found_entries = None
        if ('q' in request.GET) and request.GET['q'].strip():
            query_string = request.GET['q']

            entry_query_study = get_query(query_string, ['title', 'category', 'service', 'subject', 'industry', 'description', 'keywords', 'objective',])
            entry_query_page = get_query(query_string, ['title', 'url', 'category', 'keywords',])

            found_entries_study = Study.objects.filter(entry_query_study).order_by('title')
            found_entries_page = Page.objects.filter(entry_query_page).order_by('title')

            found_entries = list(chain(found_entries_page, found_entries_study))

        return render_to_response('search-results.html',
                         { 'query_string': query_string, 'found_entries': found_entries },
                          context_instance=RequestContext(request))

class SearchResultsView(SearchMixin, TemplateView):
    template_name = "search-results.html"

    def get_context_data(self, **kwargs):
        context = super(SearchResultsView, self).get_context_data(**kwargs)
        context["page"] = Page.objects.filter(get_query(query_string, ['title', 'url', 'category', 'keywords',])).order_by('title')
        context["study"] = Study.objects.filter(get_query(query_string, ['title', 'category', 'service', 'subject', 'industry', 'description', 'keywords', 'objective',])).order_by('title')
        return context

我得到错误 query_string is not defined。我可以将所有搜索逻辑放入 get_context_data,但是 SearchMixin 的意义何在?我要做的是:我有一个搜索框,可以搜索两个模型页面并进行研究。它适用于 FBV,但我正在尝试使用基于类的视图,以便添加 context['page'] 和 context['study'] 以便在我的模板中我可以在 if 语句中使用它们来显示结果。根据精彩的《Two Scoops of Django》一书,在模板内部进行处理是禁忌。

我无法理解的是如何访问 mixin 的 get_queryset 中的数据。否则我只是在重复自己。也许我的整个结构错了,显然我需要一些帮助。我已经阅读了大量资源,但无法将它们全部组合在一起。

我想在 CBV 中实现与 FBV 中相同的功能,并添加我提到的上下文数据以允许我执行 {% if site %}{{ site.title }}{% endif %}{% if study %}{{ study.title }}{% endif %} 等操作。

例如,我很确定 render_to_response() 不属于 get_queryset() 的末尾,但我还应该放什么,我应该把 render_to_response 放在哪里?我需要帮助将 FBV 转换为 CBV,这样我才能处理我谈到的上下文数据。

我认为也许 MultipleObjectMixin 可以完成这项工作,但不知道如何使用它并且找不到任何示例。如果有人有,请分享,因为它可能会解决问题。

如果有人可以帮助我,更正我的代码,给我一个例子,指出我正确的方向等等。将不胜感激。

旁白:自从我开始准确了解如何使用 get_queryset 和 get_context_data 以来,我遇到了很多麻烦。我了解 get_context_data 返回上下文,因此您可以在模板中使用变量等。但我看不到如何使用 get_queryset。或者它如何连接到 get_context_data。

本质上,我如何从 get_queryset 返回两个对象。那又回到了哪里?如何从 get_queryset 返回页面和学习,然后在 get_context_data 中添加我想要的上下文,最后调用 render_to_response。我只是不明白这些都是如何连接的,更不用说如何从 get_queryset 返回 2 个对象了。

一些帮助引导我朝着正确的方向前进会很有帮助。例子是最大的帮助。

【问题讨论】:

  • get_queryset 不会在 TemplateView 中被调用,除非您覆盖 dispatch 方法或在 get_context_data 方法中调用它。
  • 我可以这样调用 get_queryset,但我想做的是能够像在 FBV 中一样传递 query_string 和 found_entries 以及 context['page'] 和 context['study']这样我就可以使用 if 语句来检查结果是否是其中之一。顺便说一句,这是一个搜索表单。
  • 你应该看看ListView
  • 我知道 ListView,我已经用过很多次了,我的问题是我想用 get_queryset 使用两个对象,我想将每个对象添加到上下文中,这样我就可以在一个形式。例如,我将它们组合起来作为我的搜索结果,但我想在模板中获取结果并使用上下文对每个模型的结果进行不同的操作。
  • 您可以覆盖 get_queryset 以返回包含两个模型结果的列表。它接受任何可迭代的东西。

标签: python django


【解决方案1】:

您可以使用 CBV 遵循的解决方案可能是这样的:

 class SearchResultsView(TemplateView):
    template_name = "search-results.html"

    def find_entries(self, query_string):
        found_entries = None
        found_entries_study = None
        found_entries_page = None
        if query_string:

            entry_query_study = get_query(
                query_string,
                ['title', 'category', 'service', 'subject', 'industry', 'description', 'keywords', 'objective', ]
            )
            entry_query_page = get_query(query_string, ['title', 'url', 'category', 'keywords', ])

            found_entries_study = Study.objects.filter(entry_query_study).order_by('title')
            found_entries_page = Page.objects.filter(entry_query_page).order_by('title')

            found_entries = list(chain(found_entries_page, found_entries_study))

        return found_entries, found_entries_study, found_entries_page

    def get_context_data(self, **kwargs):
        context = super(SearchResultsView, self).get_context_data(**kwargs)
        query_string = ''
        if ('q' in self.request.GET) and self.request.GET['q'].strip():
            query_string = self.request.GET['q']
        context["all_found_entries"], context["study"], context["page"] = self.find_entries(query_string)

        return context

我知道这只是实现这一目标的一种方式。我只是想给你一个你可以遵循的想法。我希望这可以帮助你:)

【讨论】:

    【解决方案2】:

    你应该使用ListView

    class SearchResultsView(ListView):
        template_name = 'search-results.html'
        context_object_name = 'found_entries'
    
        def get_queryset(self):
            ...
            return list(chain(found_entries_page, found_entries_study))
    
        def get_context_data(self, **kwargs):
            context = super(SearchResultsView, self).get_context_data(**kwargs)
            context["query_string"] = self.request.GET.get('q')
            context["pages"] = ...
            context["studies"] = ...
            return context
    

    get_queryset 返回的列表将在模板中以found_entries 的形式提供

    【讨论】:

    • 如何像在 FBV 中那样将 found_entries 和 query_string 添加到上下文中?除此之外,到目前为止它是完美的。
    • 更新了答案。 found_entries 应该已经在上下文中可用。对于query_string,也可以添加到get_context_data
    猜你喜欢
    • 2019-04-21
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多