在Django应用程序中实现通用搜索

时间:2013-07-20 11:51:49

标签: python django search inheritance django-forms

我们有一个由大量不同视图组成的大型Django应用程序(其中一些包含表单)。与大多数大型应用程序一样,我们使用基本布局模板,其中包含应用程序中的公共布局元素(主要是页眉和页脚),我们所有视图的模板都会扩展。

我们要做的是在我们的应用程序中创建一个通用搜索框,可在每个页面上访问,允许用户在整个应用程序中执行搜索,并希望将搜索框放在标题内,这涉及到我们的基本布局模板中的form。这意味着我们的应用程序中的每个视图都需要能够处理此搜索表单的提交。提交此搜索表单后,我们需要将用户重定向到包含搜索结果的另一个视图。

然而,我们正在努力想出一个处理这个问题的模式。有没有人知道Django内置的功能有助于我们构建它?如果做不到这一点,任何人都可以建议一个好的策略来修改我们的应用程序,这样我们就可以处理这个用例,而不必修改大量现有的视图(我们目前没有资源可以做)?

请注意,此问题的重点是处理每个视图中出现的表单提交的最佳方式,而不是实现通用搜索算法的策略(我们已经想到)。< / p>

目前探索的想法

  • 我们的第一个想法是创建一个基类View类来实现处理通用搜索表单提交,并让我们的每个视图扩展它。但是,这是不可能的,因为我们已经拥有从许多不同的Django视图类继承的视图(TemplateViewListViewFormViewDeleteView是一些例子),并且能够构建我们自己的公共视图类意味着要么编写我们自己的这些Django视图类的版本来从我们自己的视图基类继承,要么重写我们的大量视图,这样他们就不会使用Django查看课程。
  • 我们的下一个想法是实现一个可以处理通用搜索表单提交的mixin,试图以允许我们继续使用不同Django视图类的方式将这个功能添加到我们的所有视图中。然而,这揭示了两个新问题:(a)我们如何在不修改每个视图成为表单视图的情况下执行此操作,以及(b)我们如何以允许表单处理逻辑的方式执行此操作很好地融入现有的FormView s?

3 个答案:

答案 0 :(得分:3)

这似乎是一个显而易见的问题,也许我忽略了一些东西。但正如其他人所说,您的通用搜索表单不应对呈现当前页面的视图发出POST请求。

每个html表单都有action属性。搜索表单的属性应指向URL。可能类似于/search。该URL后面会有一个视图,它处理来自表单的POST请求并返回搜索结果。 Django有URL模板标签,可以轻松实现。如果{% url 'myapp.views.search' %}视图函数位于search中的views模块内,myapp将为您提供正确的网址。因此,基本模板中html的相关位将类似于:

<form action="{% url 'myapp.views.search' %}">
    <input type="text" name="qs" placeholder="Search">
</form>

如果您打算在新页面上显示搜索结果,则绝对不需要返回JSON或类似内容。只需要一个看起来像这样的搜索视图

def search(request):
    query = request.POST.get('qs', '')
    results = SomeModel.objects.filter(name=query) # Your search algo goes here
    return render(request, 'search_results.html', dict(results=results))

答案 1 :(得分:1)

您可以实现一个单独的view(端点)来处理所有search queries,而不是在应用程序的每个视图上处理表单提交。 (返回JSON结果的端点),因为您不希望增加使用该视图呈现整个页面的开销。因此,搜索查询(客户端AJAX对Web服务器执行的操作)将返回JSON响应,并且Javascript可以呈现该响应。这样,您可以将search视图与其余视图隔离开来。 (Django REST在这种情况下会有所帮助)

search表单将包含在您的base模板中,因此您可以从整个应用程序访问您的搜索框,并将其提交到同一视图。并且AJAX函数将处理服务器响应以呈现它。

答案 2 :(得分:0)

您似乎只需要创建另一个SearchView,它会接收查询并显示结果。我不确定结果是否必须以不同方式显示,具体取决于执行搜索的页面,但似乎不一样。

表单与其他视图无关。您可以在基本模板中对其进行硬编码。