I am building a Flask application to manage character sheets for an RPG using an SQL database.
Currently, I have the following script that displays the list of a user's characters currently in the database.
@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")
I would like to include a button that navigates to the character sheet for the specic chosen character. So the page below would detail some of the stats for the character, and then a button would take the user to a populated character sheet on another page.
This is what I have so far for displaying a specific user's characters.
{% 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 %}
What do I use on the line with <!-- HERE -->
to make a link to the character sheet URL?
Whew, there's a lot to unpack here!
Your example is/was invalid, eg cha_name=
on the end of the db.execute()
call, and there are no calls to render_template
if a character is found, so it'll never produce a response even with a valid request.
Next, you've told Flask to pass a cha_name
parameter to your character_sheet
function, but haven't defined a parameter on the function itself.
Finally, in your template you're passing cha_name
to the url_for
function, which (so far as we can see from the sample code) isn't a route that you've defined, so can't work.
You need to include more information for us to help, such as telling us what error you're seeing. Right now, I imagine the Flask service won't even start due to the syntax error. Once that's fixed, I'd expect to see something like the following:
werkzeug.routing.BuildError: Could not build url for endpoint 'cha_name'. Did you mean 'character_sheet' instead?
I'd suggest you head back to the documentation on URL building and also look at the docs for the route
decorator . You'll see on the latter that "Flask itself assumes the name of the view function as endpoint". That means that in order to get Flask to generate a URL for your character_sheet
function, you'll need to pass that name to url_for
, and then the parameters, like this:
url_for('character_sheet', cha_name=character.name)
If a user were to rename their character, all of the URLs would change, which is a bad user experience — what would happen if they'd bookmarked a particular character, then fixed a typo in the name?
Putting this all together, here's a hopefully-better example:
# 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 %}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.