创建一个空的SQLAlchemy查询作为搜索模型的基础

时间:2015-08-09 17:16:14

标签: python flask sqlalchemy flask-sqlalchemy

我想根据多个条件搜索模型。用户输入搜索词并选择要搜索的字段。如果没有选择任何字段,我想返回一个空结果。如何创建空查询对象?或者有更好的方法来构建它吗?

results = *an empty query object*

if nameChecked:
    nameResults = System.query.filter(System.system_name.contains(searchTag))
    results = results.union(nameResults)

if descriptionChecked:
    descriptionResults = System.query.filter(System.system_description.contains(searchTag))
    results = results.union(descriptionResults)

if tagsChecked:
    tagsResults = System.query.filter(System.system_tags.contains(searchTag))
    results = results.union(tagsResults)

1 个答案:

答案 0 :(得分:0)

不是为每个字段获取单独的选中值,而是使用具有不同值但名称相同的多个复选框来获取要过滤的字段列表。

检查是否未选择任何字段,如果是,则返回空列表。否则,收集过滤器列表并将or_一起收集。在这种情况下,union不是必需的。

<form>
    <input name="q">
    <input type="checkbox" name="field" value="name">
    <input type="checkbox" name="field" value="description">
    <input type="checkbox" name="field" value="tags">
    <input type="submit">
</form>

{% if results %}
    output the results
{% endif %}
@app.route('/search')
def search():
    value = request.args['q']
    fields = set(request.args.getlist('field'))

    if not fields:
        return render_template('search.html', results=[])

    filters = []

    if 'name' in fields:
        filters.append(System.name.contains(value))

    if 'description' in fields:
        filters.append(System.description.contains(value))

    if 'tags' in fields:
        filters.append(System.tags.contains(value))

    results = System.query.filter(db.or_(*filters)).all()
    return render_template('search.html', results=results)

你可以巧妙地使用字典并压缩过滤器,但它可能效率较低。

    results = System.query.filter(db.or_(*(value for key, value in {
        'name': System.name.contains(value),
        'description': System.description.contains(value),
        'tags': System.tags.contains(value)
    }.items() if key in fields))).all() if fields else []

如果您确实需要空查询而不是空结果,则可以使用System.query.filter(False)。这是有限的用途,因为您之后无法对查询执行任何操作,任何过滤器都将被忽略。