【问题标题】:Implementing Universal Search in a Django Application在 Django 应用程序中实现通用搜索
【发布时间】:2013-07-20 11:51:49
【问题描述】:

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

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

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

请注意,这个问题的重点是处理提交出现在每个视图中的表单的最佳方式,而不是实现通用搜索算法的策略(我们已经弄清楚了)。

迄今为止探索的想法

  • 我们的第一个想法是创建一个基类View 来实现处理通用搜索表单提交,并让我们的每个视图扩展它。然而,这是不可能的,因为我们已经拥有从许多不同的 Django 视图类(TemplateViewListViewFormViewDeleteView 是一些示例)继承的视图,并且能够构建我们自己的通用视图类意味着要么编写我们自己版本的这些 Django 视图类来继承我们自己的视图基类,要么重写我们的大量视图以便它们不使用 Django 视图类。
  • 我们的下一个想法是实现一个可以处理通用搜索表单提交的 mixin,试图以一种允许我们继续使用不同 Django 视图类的方式将此功能添加到我们的所有视图中。然而,这带来了两个新问题:(a)我们如何在不修改每个视图以成为表单视图的情况下做到这一点,以及(b)我们如何以允许表单处理逻辑发挥作用的方式做到这一点与现有的FormViews 混合使用效果好吗?

【问题讨论】:

    标签: python django search inheritance django-forms


    【解决方案1】:

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

    每个 html 表单都有一个 action 属性。您的搜索表单的属性应该指向一个 URL。可能类似于/search。该 url 后面会有一个视图,它处理来自表单的 POST 请求并返回搜索结果。 Django 有 URL 模板标签来简化此操作。如果{% url 'myapp.views.search' %} 位于myappviews 模块内,{% url 'myapp.views.search' %} 将为您提供search 视图函数的正确URL。因此,您的基本模板中的相关 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))
    

    【讨论】:

    • 天哪 - 很惭愧我没有看到,当然这是正确的做法。我想我的头脑中的问题过于复杂了:)顺便说一句,我假设网址应该被{% ... %}包围?
    • 哈! :) 我想知道是不是这样。是的,当然你是对的。我会编辑答案。我通常使用命名的网址。我认为这看起来更好一些。所以{% url search %}.
    【解决方案2】:

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

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

    【讨论】:

    • 这听起来是正确的——我在问题中忘记提到的一件事(现已更新)是,在提交搜索表单时,我们需要重定向到包含搜索结果的视图。你知道如何以这种方式实现一个单独的端点的例子吗?
    • 这里是实现它的快速入门指南django-rest-framework.org/tutorial/1-serialization.html
    • 这看起来很有希望——看起来我们可以使用一些自定义 javascript 将其余调用挂钩到搜索表单中,并且该框架可以处理将用户重定向到另一个视图作为响应。非常感谢您的意见,现在可以玩这个了:)
    • @aychedee 提出了一个更简单的解决方案来满足我们的需求,但对于一个简洁的解决方案仍然 +1。
    【解决方案3】:

    您似乎只需要创建另一个 SearchView 来接受查询并显示结果。我不确定结果是否必须根据从哪个页面执行搜索而以不同的方式显示,但它看起来不像。

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

    【讨论】:

    • 感谢您的意见 - 尽管我认为这并不能完全解决我们的问题。实现一个单独的视图来显示结果不是问题——我们更多的是想弄清楚我们如何编写可以响应搜索表单提交的逻辑,但独立于当前正在显示的视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 2011-01-11
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多