【问题标题】:How do I use Flask's url_for in a template?如何在模板中使用 Flask 的 url_for?
【发布时间】:2021-02-25 10:48:34
【问题描述】:

我正在构建一个 Flask 应用程序来管理使用 SQL 数据库的 RPG 字符表。

目前,我有以下脚本可以显示数据库中当前用户的字符列表。

@app.route("/<cha_name>")
@login_required
def character_sheet():
    characters = db.execute(
        """SELECT
          *
        FROM
            characters
        WHERE
            user_id = :user_id AND
            name = :cha_name
        """,
        user_id=session["user_id"],
        cha_name="???",
    )

    if not characters:
        return render_template("add_char.html")

我想包含一个按钮,用于导航到特定所选字符的字符表。因此,下面的页面将详细介绍角色的一些统计信息,然后一个按钮会将用户带到另一个页面上已填充的角色表。

这是我目前用于显示特定用户字符的方法。

{% extends "main.html" %}

{% block title %}
    Characters
{% endblock %}

{% block main %}
      <table border = 1>
         <thead>
            <td>Player</td>
            <td>Name</td>
            <td>Race</td>
            <td>Class</td>
            <td>Level</td>
            <td>Status</td>
            <td>View</td>
         </thead>

         {% for row in rows %}
            <tr>
               <td>{{ character["user"] }}</td>
               <td>{{ character["name"] }}</td>
               <td>{{ character["race"] }}</td>
               <td>{{ character["cha_class"] }}</td>
               <td>{{ character["level"] }}</td>
               <td>{{ character["status"] }}</td>
               <td><a href={{ url_for('cha_name') }}>View Sheet</a></td> <!-- HERE -->
            </tr>
         {% endfor %}

      </table>
      <a href = "/add_char">Add a new Character</a>
      <a href = "/">Go back to home page</a>

   </body>
{% endblock %}

我在&lt;!-- HERE --&gt; 的行上使用什么来链接到字符表URL?

【问题讨论】:

  • 我已编辑以使问题真正有意义。

标签: python html flask jinja2 url-for


【解决方案1】:

哇,这里有很多东西要解压!

您的示例无效/无效,例如cha_name=db.execute() 调用结束时,如果找到一个字符,则不会调用render_template,因此即使请求有效,它也永远不会产生响应。

接下来,您已告诉 Flask 将 cha_name 参数传递给您的 character_sheet 函数,但尚未在函数本身上定义参数。

最后,在您的模板中,您将 cha_name 传递给 url_for 函数,这(就我们从示例代码中可以看出)不是您定义的路由,所以不能工作。

您需要提供更多信息以便我们提供帮助,例如告诉我们您遇到的错误。现在,我想 Flask 服务甚至不会因为语法错误而启动。一旦解决了这个问题,我希望看到如下内容:

werkzeug.routing.BuildError: Could not build url for endpoint 'cha_name'. Did you mean 'character_sheet' instead?

我建议您返回documentation on URL building 并查看docs for the route decorator。您将在后者中看到“Flask 本身将视图函数的名称假定为端点”。这意味着为了让 Flask 为您的 character_sheet 函数生成 URL,您需要将该名称传递给 url_for,然后是参数,如下所示:

url_for('character_sheet', cha_name=character.name)

如果用户要重命名他们的角色,所有的 URL 都会改变,这是一种糟糕的用户体验 - 如果他们为特定角色添加了书签,然后修正了名称中的拼写错误,会发生什么情况?

把所有这些放在一起,这是一个希望更好的例子:

# app.py
@login_required
@app.route("/<character_id>")
def character_sheet(character_id):
    characters = db.execute(
        """SELECT
          *
        FROM
            characters
        WHERE
            id = :id AND
            user_id = :user_id
        """,
        id=character_id,
        user_id=session["user_id"],
    )

    if not characters:
        return abort(404)

    return render_template(
        "characters/sheet.html",
        character=characters[0],
    )
<!-- templates/characters/list.html -->
{% extends "main.html" %}

{% block title %}
    Characters
{% endblock %}

{% block main %}
    <table>
         {% for character in characters %}
            <tr>
               <td>{{ character.name }}</td>
               <td><a href={{ url_for('character_sheet', character_id=character.id) }}>View Sheet</a></td>
            </tr>
         {% endfor %}
    </table>
    <a href = "{{ url_for('add_char') }}">Add a new Character</a>
{% endblock %}

【讨论】:

  • 太棒了,感谢您的帮助和指导哦,互联网上的聪明陌生人。
猜你喜欢
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-30
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多