0

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

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

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

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

迄今为止探索的想法

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

3 回答 3

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))
于 2013-07-20T14:44:39.290 回答
1

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

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

于 2013-07-20T12:05:43.297 回答
0

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

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

于 2013-07-20T12:17:46.857 回答