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

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)

最佳答案

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

检查是否未选择任何字段,如果是,则返回一个空列表。否则,请收集过滤器列表,并一起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)。这是有限的用途,因为此后您无法对查询执行任何操作,所有过滤器都会被忽略。

10-07 15:36