首先flask支持全文搜索的模块目前用的比较多的只有whooshalchemy以及whooshalchemyplus两个,不过都仅仅支持英文全文搜索,中文的话需要先进行分词处理,然后才能够使用whooshalchemyplus搜到,而中文分词在pyhton中莫过于jieba(做最好的 Python 中文分词组件)。
最近使用flask建站时,一直找不到有效的中文全文搜索方法,网上这方面的资料也比较少,并且有效的就更捉急了,参考了网上的一些说法加上自己的摸索,最终找到了行之有效的实现方式,现在记录下来。
一、安装
-
pip install flask_whooshalchemyplus
-
pip install jieba
flask_whooshalchemyplus资料: https://pypi.python.org/pypi/Flask-WhooshAlchemyPlus/0.7.5
jieba资料: https://pypi.python.org/pypi/jieba/
二、使用
1.(app/__init__.py初始化文件)
(1). 导入flask_whooshalchemyplus用来建立搜索
import flask_whooshalchemyplus
(2).然后在工厂函数create_app中进行初始化app, 即
flask_whooshalchemyplus.init_app(app)
2.(app/models.py模板文件)
导入 jieba, 用来中文分词
from jieba.analyse.analyzer import ChineseAnalyzer
在Post类中添加:
-
__searchable__ = ['body', 'title']
-
__analyzer__ = ChineseAnalyzer()
以便进行文章标题及内容的修改。
3.(app/main/view.py视图文件)
(1). 在视图函数index()中判断是否有表单提交中最后添加:
flask_whooshalchemyplus.index_one_model(Post)
用来将每一次的提交加入索引
(2). 新添加两个路由函数:(搜索及搜索结果)
-
@main.route('/search', methods = ['POST'])
-
def search():
-
if not request.form['search']:
-
return redirect(url_for('.index'))
-
return redirect(url_for('.search_results', query = request.form['search']))
-
@main.route('/search_results/<query>')
-
def search_results(query):
-
results = Post.query.whoosh_search(query).all()
-
return render_template('search_results.html', query = query, results = results)
4. (前端)
(1). 在base.html的导航栏中添加搜索框:
-
<div class="col-lg-4">
-
{% if current_user %}
-
<form class="navbar-form navbar-left" action="{{url_for('main.search')}}" method="POST">
-
<div class="form-group">
-
<input type="text" class="form-control" placeholder="站内搜索" name="search" >
-
</div>
-
<button type="submit" class="btn btn-default">搜索</button>
-
</form>
-
{% endif %}
-
</div>
(2). search_results.html文件
-
{% extends "base.html" %}
-
{% block title %}Searching{% endblock %}
-
{% block page_content %}
-
<div class="page-header">
-
<h1>搜索关键词: "{{query}}"</h1>
-
</div>
-
<ul class="posts">
-
{% for post in results %}
-
<li class="post">
-
<div class="post-content">
-
<div class="post-date">{{ moment(post.timestamp).fromNow() }}</div>
-
<div class="post-author"><a href="{{ url_for('.user', username=post.author.username) }}">{{ post.author.username }}</a></div>
-
<div class="post-body">
-
{% if post.body_html %}
-
{{ post.body_html | safe }}
-
{% else %}
-
{{ post.body }}
-
{% endif %}
-
</div>
-
<div class="post-footer">
-
<a href="{{ url_for('.post', id=post.id) }}">
-
<span class="label label-success">详情</span>
-
</a>
-
<a href="{{ url_for('.post', id=post.id) }}#comments">
-
<span class="label label-primary">{{ post.comments.count() }} 评论</span>
-
</a>
-
</div>
-
</div>
-
</li>
-
{% endfor %}
-
</ul>
-
{% endblock %}
到这里基本已经完成了。
三、效果
1. 页面:搜索框
2.中文搜索结果