全文检索
flask_whooshalchemyplus: flask第三方扩展,支持中文检索的全文索搜索组件。
jieba: “结巴”中文分词:做最好的 Python 中文分词组件
一、安装
# 全文检索模块
pip install flask_whooshalchemyplus
# jieba中文分词
pip install jieba
配置:
WHOOSH_BASE = 'path/to/whoosh/base'
WHOOSH_BASE 索引保存地址,默认保存在项目目录下的 whoosh_index目录下。
项目中使用全文检索:
根据商品的标题模糊搜索
修改商品标题模型类
from jieba.analyse.analyzer import ChineseAnalyzer
class GoodsTitle(db.Model):
"""商品主表"""
__tablename__ = 'g_title' # 实际数据库中表名称
__searchable__ = ['title',] # 指定需要检索的字段的字段
__analyzer__ = ChineseAnalyzer() # 指定使用结巴中文分词
id = db.Column(db.INTEGER, primary_key=True)
title = db.Column(db.String(100))
goods = db.relationship('GoodsInfo', backref='g_title')
def __repr__(self):
return self.title
1、将searchable字段添加到指定要编入索引的字段(如str)的模型中。 2、analyzer 指定使用分词引擎,使用结巴中文分词,flask_whooshalchemyplus默认的分词也支持中文。
在创建flask实例的init.py 文件中修改添加
import flask_whooshalchemyplus
def create_app():
app = Flask(__name__) # type:Flask
app.config.from_object(Config)
# 添加自定义的路由转换器
app.url_map.converters["re"] = RegexConverter
session.init_app(app)
db.init_app(app)
cache.init_app(app)
# 延时导入蓝图,防止循环导入
from shop.views import app as blu_app
from shop.api_1_0 import api
app.register_blueprint(blu_app)
app.register_blueprint(api, url_prefix='/api/v1')
flask_whooshalchemyplus.init_app(app) # 实例化全文索引模块
return app
搜索
whoosh_search 方法
示例:
@app.route('/search_results/<query>')
def search_results(query):
results = GoodsTitle.query.whoosh_search(query, 100, like=True).all()
print(results)
return 'ok'
whoosh_search 参数说明:
query: 用户搜索文本 limit: 返回几条数据 fields: 在指定的字段搜索,默认全部字段搜索 like: 是否模糊匹配,默认false为全匹配,设置成True,为模糊匹配。
搜索结果:
如果没有符合条件返回[]空列表,如果有条件,则返回符合条件对象。
CSRF 保护
为什么需要 CSRF? Flask-WTF 表单保护你免受 CSRF 威胁,你不需要有任何担心。尽管如此,如果你有不包含表单的视图,那么它们仍需要保护。 例如,由 AJAX 发送的 POST 请求,然而它背后并没有表单。
实现 为了能够让所有的视图函数受到 CSRF 保护,你需要开启 CsrfProtect 模块:
from flask_wtf.csrf import CsrfProtect
CsrfProtect(app)
像任何其它的 Flask 扩展一样,你可以惰性加载它:
from flask_wtf.csrf import CsrfProtect
csrf = CsrfProtect()
def create_app():
app = Flask(__name__)
csrf.init_app(app)
如果模板中存在表单,可以直接在表单中添加模板标签
<form method="post" action="/">
{{ form.csrf_token }}
</form>
如果不是用的表单:
<form method="post" action="/">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>
ajax中处理csrf:
推荐的方式是在 标签中渲染 CSRF 令牌:
<meta name="csrf-token" content="{{ csrf_token() }}">
在我们的项目中可以在base.html 这个父模板中添加。
也可以直接在js中使用标签:
<script type="text/javascript">
var csrftoken = "{{ csrf_token() }}"
</script>
ajax中使用:
//先从meta标签中取出csrf_token
var csrftoken = $('meta[name=csrf-token]').attr('content');
$.ajax({
type:'POST',
url:'/order/',
data:order_cart_id,
headers: {
"X-CSRFToken": csrftoken,
},
//ajax发送的时候,在请求头部添加"X-CSRFToken"字段
success:function (data) {
if (data.errno == 10000){
window.location.href = data.url+"?oid=" + data.oid
}else {layer.msg(data.errmsg)}
}
})