我在PostgreSQL数据库上使用Flask / SQLAlchemy处理Python应用程序。尝试实现Flask / jQuery自动填充搜索表单,如Flask AJAX Autocomplete
所述在我的_base模板中,我有:
<script type=text/javascript>
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>
<script type="text/javascript">
$(function() {
$( "#searchfood" ).autocomplete({
source: function( request, response ) {
$.getJSON($SCRIPT_ROOT + "/_search_food", {
search: request
}, function( data ) {
response( $.map( data.results, function( item ) {
return {
label: item.name,
value: item.id
}
}));
});
}
});
});
</script>
在app.py中:
@app.route('/_search_food')
def search_food():
search = request.args.get('search')
results = Foods.query.filter(Foods.name.like('%' + search + '%')).all()
return jsonify(results)
Ajax调用似乎有效,因为控制台会向search_food显示触发器,但是如果我直接浏览页面http://localhost:5000/_search_food?search%5Bterm%5D=Mar并出现500错误:TypeError: cannot concatenate 'str' and 'NoneType' objects
。由结果查询触发:
results = Foods.query.filter(Foods.name.like('%' + search + '%')).all()
它是否从数据库中获取结果?或者我必须将输入转换为其他格式? Foods模型中的name对象是一个字符串。
答案 0 :(得分:2)
search
为None
,因为您的GET请求中没有此类参数,因此request.args.get('search')
返回了默认值。
相反,您的参数称为search[term]
,因为jQuery传递了一个具有term
属性的对象。提取它:
$.getJSON($SCRIPT_ROOT + "/_search_food", {
search: request.term
},
否则jQuery会尝试使用PHP约定来序列化对象。
另见jQueryUI autocomplete documentation:
[...] 回调有两个参数:
- 具有单个
term
属性的请求对象,该属性引用文本输入中当前的值。[...]
请注意,您不能只将Food()
个对象转换为JSON。选择要在自动填充小部件中显示的属性;它需要一个字符串数组或一个具有label
和value
属性的对象数组。
您可以使用列表推导来生成:
results = Foods.query.filter(Foods.name.like('%' + search + '%')).all()
return jsonify(results=[{'label': f.name, 'value': f.id} for f in results])
使用名称作为自动完成值。请注意,出于安全原因,jsonify()
始终生成JSON对象,因此您需要在JavaScript端提取数组:
$.getJSON($SCRIPT_ROOT + "/_search_food", {
search: request
}, function( data ) { response(data.results); });