首先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.中文搜索結果