调用时通过 Jinja 模板变量问题在 Flask 中排序

Sorting in Flask via Jinja template variable issue when called

我有一个 HTML 下拉表单不起作用,所以我只是将其更改为按钮进行测试(我对 Flask 很陌生,一般来说 python 所以我实验中)。

我正在尝试让用户选择按添加时间、姓名等对帖子进行排序。目前我只是在试验这三个,它们是按钮形式(我工作时会在下拉列表中出如何):

<form action="{{ url_for('filters') }}" name="sort" method="POST">
        <button type="submit" id="latest" class="btn">Latest</button>
        <button type="submit" id="oldest" class="btn">Oldest</button>
        <button type="submit" id="names" class="btn">Name</button>
</form>

这一切都在名为:questions.html

的页面上

过滤器应用程序是: @app.route("/filters", methods=["GET", "POST"])

def filters():
    sort = request.form.get("sort")
    if sort == "oldest":
        questions = mongo.db.questions.find().sort("added_on", 1)
    if sort == "latest":
        questions = mongo.db.questions.find().sort("added_on", -1)
    if sort == "names":
        questions = mondo.db.questions.find().sort("created_by", 1)           
    
    return render_template("questions.html", questions=questions)

我已经在提问了,我已经通过以下方式正确显示了它们:

@app.route("/get_questions")
def get_questions():
    questions = mongo.db.questions.find().sort("added_on", -1)
    return render_template("questions.html", questions=questions)

但是当我尝试使用按钮调用排序时出现此错误:

UnboundLocalError: local variable 'questions' referenced before assignment

它将它调用到第 40 行,即:过滤器函数中的 return render_template("questions.html", questions=questions)

那么,我做错了什么?我需要做什么才能将用户排序选项放入下拉列表中以便它们起作用?

谢谢:)

HTML 表单没有 name 属性,因此您可以删除该属性。您可能想要做的是向您的按钮添加一个 name 和一个 value 属性,因为名称-值对是在提交表单时发送到服务器的内容。

稍后,当您确认代码有效时,您可以像最初计划的那样将按钮换回下拉菜单 select 输入。对于按钮,它类似于:

<form action="{{ url_for('filters') }}" method="POST">
    <button type="submit" name="sort" value="latest" class="btn">Latest</button>
    <button type="submit" name="sort" value="oldest" class="btn">Oldest</button>
    <button type="submit" name="sort" value="names" class="btn">Name</button>
</form>

对于基于 select 的下拉菜单,它类似于:

<form action="{{ url_for('filters') }}" method="POST">
    <select name="sort">
        <option value="latest">Latest</option>
        <option value="oldest">Oldest</option>
        <option value="names">By name</option>
    </select>
    <button type="submit">Apply filter</button>
</form>

问题的第二部分——UnboundLocalError——是因为 none 检查 sort 变量的测试产生一个真值,因此 questions变量未定义,换句话说,未绑定。例如,如果请求中提供了 none,您可以为 sort 使用默认值,或者使用不同的 if 结构,其中 ifelifelseelse 作为默认值。类似于:

def filters():
    sort = request.form.get("sort")

    if sort == "oldest":
        questions = mongo.db.questions.find().sort("added_on", 1)
    elif sort == "latest":
        questions = mongo.db.questions.find().sort("added_on", -1)
    elif sort == "names":
        questions = mondo.db.questions.find().sort("created_by", 1)
    else:
        # if `sort` is none of the above, default to showing the latest questions
        questions = mongo.db.questions.find().sort("added_on", -1)         
    
        return render_template("questions.html", questions=questions)

编辑

我对 UnboundLocalError 的回答保持不变,但当我重新阅读你的问题时,我意识到有一种更简洁的方法可以做到这一点。过滤器应该由查询字符串参数处理,而不是表单数据。使用查询字符串参数执行此操作意味着 URL 将与应用的过滤器一起共享。

总体思路是,单个路由处理显示问题以及处理过滤器的应用。你可以尝试类似的东西:

@app.route("/questions")
def questions():
    sort = request.args.get("sort")
    if sort == "oldest":
        questions = mongo.db.questions.find().sort("added_on", 1)
    elif sort == "latest":
        questions = mongo.db.questions.find().sort("added_on", -1)
    elif sort == "names":
        questions = mondo.db.questions.find().sort("created_by", 1)
    else:
        # if `sort` is none of the above, default to showing the latest questions
        questions = mongo.db.questions.find().sort("added_on", -1) 
    return render_template("questions.html", questions=questions)

过滤器按钮看起来像这样。提交 for 时,过滤器将作为查询参数添加到 URL.

<form action="{{ url_for('questions') }}" method="GET">
    <button type="submit" name="sort" value="latest" class="btn">Latest</button>
    <button type="submit" name="sort" value="oldest" class="btn">Oldest</button>
    <button type="submit" name="sort" value="names" class="btn">Name</button>
</form>