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

2024-05-10 01:12:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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”,方法=[“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行,即filters函数中的:return render_template("questions.html", questions=questions)

那么,我做错了什么?我需要做什么才能让用户排序选项进入下拉列表,使其正常工作

谢谢:)


Tags: formiddb排序htmltypebuttonfind
1条回答
网友
1楼 · 发布于 2024-05-10 01:12:48

HTML表单没有name属性,因此可以删除该属性。您可能想做的是在按钮中添加namevalue属性,因为提交表单时会将名称-值对发送到服务器

稍后,当您验证代码是否有效时,您可以像最初计划的那样,将按钮调回下拉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是因为检查sort变量的测试都不会产生真值,因此questions变量未定义,换句话说,未绑定。例如,如果请求中没有提供sort的默认值,则可以使用不同的if结构,其中ifelifelse作为默认值。比如:

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>

相关问题 更多 >