【问题标题】:Sorting in Flask via Jinja template variable issue when called调用时通过 Jinja 模板变量问题在 Flask 中排序
【发布时间】:2020-12-29 14:13:15
【问题描述】:

我有一个 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)

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

非常感谢:)

【问题讨论】:

    标签: python mongodb sorting flask jinja2


    【解决方案1】:

    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 变量的测试都没有产生 True 值,因此 questions 变量是未定义的,换句话说,是未绑定的。例如,如果请求中没有提供 sort 的默认值,或者使用不同的 if 结构,ifelifelse,您可以使用 else作为默认值。比如:

    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)
    

    编辑

    我对@9​​87654338@ 的回答保持不变,但当我重新阅读您的问题时,我意识到有一种更简洁的方法可以做到这一点。过滤器应该由查询字符串参数处理,而不是表单数据。使用查询字符串参数执行此操作意味着 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>
    
    

    【讨论】:

    • 感谢您的回复。我喜欢你所做的,但它仍然让我没有任何工作可悲。我什至没有收到错误。
    • 我已经更新了我的答案。关于 UnboundLocalError 的评论保持不变,但我认为有一个更清洁的过滤解决方案,它不涉及两个单独的路由。
    • 啊,我实际上在我的html中发现了一个错误,我只是通过它排序。我认为你是对的。
    猜你喜欢
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    相关资源
    最近更新 更多