搜索视图函数
完成搜索功能的最后一项功能是接收搜索表单的视图函数。 该视图函数将被附加到 /search 路由,以便你可以发送类似 http://localhost:5000/search?q=search-words 的搜索请求,就像 Google 一样。
app/main/routes.py :搜索视图函数。
@bp.route('/search')
@login_required
def search():
if not g.search_form.validate():
return redirect(url_for('main.explore'))
page = request.args.get('page', 1, type=int)
posts, total = Post.search(g.search_form.q.data, page,
current_app.config['POSTS_PER_PAGE'])
next_url = url_for('main.search', q=g.search_form.q.data, page=page + 1) \
if total > page * current_app.config['POSTS_PER_PAGE'] else None
prev_url = url_for('main.search', q=g.search_form.q.data, page=page - 1) \
if page > 1 else None
return render_template('search.html', title=_('Search'), posts=posts,
next_url=next_url, prev_url=prev_url)
你已经看到,在其他表单中,我使用 form.validate_on_submit()
方法来检查表单提交是否有效。 不幸的是,该方法只适用于通过 POST
请求提交的表单,所以对于这个表单,我需要使用 form.validate()
,它只验证字段值,而不检查数据是如何提交的。 如果验证失败,这是因为用户提交了一个空的搜索表单,所以在这种情况下,我只能重定向到了显示所有用户动态的发现页面。
SearchableMixin
类中的 Post.search()
方法用于获取搜索结果列表。 分页的处理方式与主页和发现页面非常类似,但如果没有 Flask-SQLAlchemy 的“分页”对象的帮助,生成下一个和前一个链接会有点棘手。 这是从 Post.search()
返回的结果总数的用途所在。
一旦计算出搜索结果和分页链接的页面,剩下的就是渲染一个包含所有这些数据的模板。 我已经想出了一种重用 index.html 模板来显示搜索结果的方法,但考虑到有一些差异,我决定创建一个专用于显示搜索结果的 search.html 专属模板, 以 _post.html 子模板的优势来渲染搜索结果:
app/templates/search.html :搜索结果模板。
{% extends "base.html" %}
{% block app_content %}
<h1>{{ _('Search Results') }}</h1>
{% for post in posts %}
{% include '_post.html' %}
{% endfor %}
<nav aria-label="...">
<ul>
<li>
<a href="{{ prev_url or '#' }}">
<span aria-hidden="true">←</span>
{{ _('Previous results') }}
</a>
</li>
<li>
<a href="{{ next_url or '#' }}">
{{ _('Next results') }}
<span aria-hidden="true">→</span>
</a>
</li>
</ul>
</nav>
{% endblock %}
如果前一个和下一个链接的渲染逻辑有点混乱,可能查看 分页组件 的 Bootstrap 文档会有所帮助。
感想如何? 本章的内容有些激进,因为里面介绍了一些相当先进的技术。 本章中的一些概念可能需要你花一些时间才能有所领悟。本章最重要的一点是,如果你想使用与 Elasticsearch 不同的搜索引擎,只需要重写 app/search.py 即可。 通过这项工作的另一个重要好处是,如果我需要为另外的数据库模型添加搜索支持,我可以简单地通过向它添加 SearchableMixin
类,为 __searchable__
属性填写要索引的字段列表和 SQLAlchemy 事件处理程序的监听即可。 我认为这些努力是值得的,因为从现在起,处理全文索引将会变得十分容易。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论