我如何在模板中使用 Flask 的 url_for?
How do I use Flask's url_for in a template?
我正在构建一个 Flask 应用程序来使用 SQL 数据库管理 RPG 的角色 sheet。
目前,我有以下脚本显示数据库中当前用户的角色列表。
@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")
我想包含一个按钮,用于导航到特定所选字符的字符 sheet。因此,下面的页面将详细介绍角色的一些统计信息,然后一个按钮会将用户带到另一个页面上的填充角色 sheet。
这是我目前显示特定用户角色的方法。
{% 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 %}
在<!-- HERE -->
那一行用什么来给sheetURL字符做一个link?
哇,这里有很多东西要打开!
你的例子is/was无效,例如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 and also look at the 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 %}
我正在构建一个 Flask 应用程序来使用 SQL 数据库管理 RPG 的角色 sheet。
目前,我有以下脚本显示数据库中当前用户的角色列表。
@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")
我想包含一个按钮,用于导航到特定所选字符的字符 sheet。因此,下面的页面将详细介绍角色的一些统计信息,然后一个按钮会将用户带到另一个页面上的填充角色 sheet。
这是我目前显示特定用户角色的方法。
{% 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 %}
在<!-- HERE -->
那一行用什么来给sheetURL字符做一个link?
哇,这里有很多东西要打开!
你的例子is/was无效,例如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 and also look at the 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 %}