Django Mixins搜索功能

时间:2015-07-13 01:33:26

标签: python django

我有一个工作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未定义。我可以把所有的搜索逻辑放到get_context_data中,但那么SearchMixin有什么意义呢?我想要做的是:我有一个搜索框,搜索两个模型页面和研究。它适用于FBV,但我尝试使用基于类的视图,以便我添加上下文['页面']和上下文[' study']以便我的模板我可以在if语句中使用它们来显示结果。根据Django的精彩书籍Two Scoops,在模板内进行处理是禁忌。

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

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

例如,我非常确定render_to_response()不属于get_queryset()的末尾,但是我还会把它放在那里,我将把render_to_response放在哪里?我需要帮助将FBV翻译成CBV,这样我才能完成我所谈到的上下文数据。

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

如果有人可以帮助我,请更正我的代码,给我一个例子,指出我正确的方向,等等。非常感谢。

ASIDE:自从我开始准确理解如何使用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个对象。

在正确的方向上引导我的一些帮助会有很大帮助。例子是最大的帮助。

2 个答案:

答案 0 :(得分:1)

您应该使用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

答案 1 :(得分: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

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