I am trying to dynamically generate routes in Flask from a list. I want to dynamically generate view functions and endpoints and add them with add_url_rule
.
This is what I am trying to do but I get a "mapping overwrite" error:
routes = [
dict(route="/", func="index", page="index"),
dict(route="/about", func="about", page="about")
]
for route in routes:
app.add_url_rule(
route["route"], #I believe this is the actual url
route["page"], # this is the name used for url_for (from the docs)
route["func"]
)
app.view_functions[route["func"]] = return render_template("index.html")
How to create dynamic URLs in Python Flask with url_for()? To create dynamic URLs in Python Flask with url_for(), we can call url_for with the name of the view function and the URL parameter values. @app. route('/<variable>/add', methods=['GET', 'POST']) def add(variable): # ...
Flask – URL Building Advertisements. The url_for() function is very useful for dynamically building a URL for a specific function. The function accepts the name of a function as first argument, and one or more keyword arguments, each corresponding to the variable part of URL.
In some cases you can reuse a Flask route function for multiple URLs. Or you want the same page/response available via multiple URLs. In that case you can add a second route to the function by stacking a second route decorator to the function. The code below shows how you use the a function for multiple URLs.
You have one problem with two possible solutions. Either:
route[func]
directly reference a function, not a string. In this case, you don't have to assign anything to app.view_functions
.Or:
Leave out the third argument of app.add_url_rule
, and assign a function to app.view_functions[route["page"]]
. The code
return render_template("index.html")
is not a function. Try something like
def my_func():
return render_template("index.html")
# ...
app.view_functions[route["page"]] = my_func
I'd recommend the first option.
Source: the docs.
Use variable parts in the URL. Something like this:
@app.route('/<page>')
def index(page):
if page=='about':
return render_template('about.html') # for example
else:
some_value = do_something_with_page(page) # for example
return render_template('index.html', my_param=some_value)
Not too familiar with Flask, so it is possible that there is a cleaner way to do this. (If someone who is knowledgeable about Flask thinks that my method is inherently wrong, I'll gladly delete my answer if they explain why in a comment.) Now that I got that disclaimer out of the way, here are my thoughts:
app.route("/")
is a decorator function. The @
notation is just syntactic sugar for something like index = app.route("/")(index)
. Therefore, you should be able to do something like this...
routes = [
("/", index),
("/about", about)
]
for route, view_func in routes:
view_func = app.route(route)(view_func)
which would allow you to create the Flask routes from dynamically created routes and functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With