'How can I create a Dynamic Route in Flask from an existing View?
I am somewhat stuck trying to figure out how to configure a route in Flask properly. I'll try and give some contextual information first:
My web app allows Users to join Clubs. A user can join 1 or many clubs.
Each Club has a dashboard page, and I am serving that to the user via Blueprint:
Route:
@club_bp.route("/clubdashboard/<int:Club_id>", methods=["GET"])
@login_required
def clubdashboard(Club_id):
"""Logged-in User Club Dashboard."""
selectedClub=Club.query.get(Club_id)
return render_template(
"clubdashboard.html",
title="Club Dashboard",
current_user=current_user,
clubname=selectedClub.name,
members = selectedClub.members
)
Jinja2 Template Snippet:
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
{% for club in current_user.users %}
<a class="dropdown-item" href="{{ url_for('club_bp.clubdashboard', Club_id=club.id) }}">{{ club.name }}</a>
{% endfor %}
</div>
The currentuser.users property contains a List of id values for clubs the user is a member of (the .users property is crappy naming on my part, it's on my todo list to fix it.)
The Jinja snippet creates a dropdown menu in the navbar to allow the clubdashboard route to serve an individual dashboard per club.
What I am looking to do is within the Club Dashboard view have a link called "Customize" that, in future, can do a bunch of things (not exactly relevant just yet), but first i'd like to just figure out how to serve the page properly.
For any individual club dashboard I get a URL such as:
http://127.0.0.1:5000/clubdashboard/763074009760399361
What i'd like is simply to serve a URL like this:
http://127.0.0.1:5000/clubdashboard/763074009760399361/customize
But I can't seem to figure out how to do it. Any ideas on where to start would be greatly appreciated.
Solution 1:[1]
Simply add the route:
@club_bp.route("/clubdashboard/<int:club_id>/customize", methods=["GET"])
@login_required
def club_customize(club_id):
"""Customize whatever is specific to your club"""
return "TODO: Actually make it work"
And then you can route to it with a simple url_for("club_bp.club_customize", club_id=club.id)
In order to have access to the club ID in clubdashboard.html you need to pass in either the selected club or the club ID in your clubdashboard function:
def clubdashboard(Club_id):
"""Logged-in User Club Dashboard."""
selectedClub=Club.query.get(Club_id)
return render_template(
"clubdashboard.html",
title = "Club Dashboard",
current_user = current_user,
clubname = selectedClub.name,
club = selectedClub, # <-- This lets `club.id` work in the template
members = selectedClub.members
)
Solution 2:[2]
I've managed to get it working how i'd like. Not sure if it's exactly the best way to do it so happy to be corrected still, but here goes:
In my existing Dashboard route, I took the club ID value and stored it in a user session variable:
@club_bp.route("/clubdashboard/<int:Club_id>", methods=["GET"])
@login_required
def clubdashboard(Club_id):
"""Logged-in User Club Dashboard."""
selectedClub=Club.query.get(Club_id)
session['selectedclubid'] = selectedClub.id
return render_template(
"clubdashboard.html",
title="Club Dashboard",
current_user=current_user,
clubname=selectedClub.name,
members = selectedClub.members
)
I then pass the session variable into the Club Rules (Customise) route from the Jinja template:
<a class="nav-link" href="{{ url_for('club_bp.rules', Club_id=session['selectedclubid']) }}">Club Rules</a>
Route:
@club_bp.route("/clubdashboard/<int:Club_id>/rules", methods=["GET"])
@login_required
def rules(Club_id):
"""Logged-in User Club Dashboard."""
selectedClub=Club.query.get(Club_id)
return render_template(
"clubrules.html",
title="Club Rules",
current_user=current_user,
clubname=selectedClub.name,
members = selectedClub.members
)
This route performs a query for the relevant data and displays. I might have been overthinking the issue.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Vaanderal |
