Creating dynamic flask route
Question:
I’m attempting to create a dynamic flask route. I want to create a parallel page for my route that internal users can see when they add ‘vo/’ before the URL. So essentially there are two different routes /vo/feedbackform
and /feedbackform
. I know I could just create two routes in the app, but I’m hoping I can optimize.
@app.route('/<x>feedbackform', methods=['GET', 'POST'])
def feedback_portal(x):
if x == 'vo/':
return render_template('feedback_vo.html', title='Inquiry Submission')
elif x == '':
return render_template('feedback.html', title='Inquiry Submission')
So far, this only works when the URL using the vo/ in the x
part of the URL by my elif
isn’t working, and I get an error.
Answers:
I don’t think this is supported by Flask.
For your case that you have only 2 paths to support, you can add two decorators/routes to same function and then inspect the request.path
to render the appropriate template:
from flask import request
@app.route('/vo/feedbackform', methods=['GET', 'POST'])
@app.route('/feedbackform', methods=['GET', 'POST'])
def feedback_portal():
if request.path[0:4] == '/vo/':
return render_template('feedback_vo.html', title='Inquiry Submission')
else:
return render_template('feedback.html', title='Inquiry Submission')
If you had multiple options to support instead of just /vo/
, you could look into declaring the dynamic part as path
:
@app.route('/<path:x>feedbackform', methods=['GET', 'POST'])
And add one more route to handle the static /feedbackform
.
Building off of @ilias-sp’s answer, I was able to use this code:
@app.route('/feedbackform/', methods=['GET', 'POST'], defaults={'x': None})
@app.route('/<x>/feedbackform/', methods=['GET', 'POST'])
def feedback_portal(x):
if x=='vo':
return render_template('feedback_vo.html', title='Inquiry Submission')
elif x==None:
return render_template('feedback.html', title='Inquiry Submission')
I don’t know your reasons for wanting to have a single handler but if the snippet you provided is all there is to it, I don’t see much in common between the two routes to warrant a single handler especially if you are going to use if-else to handle each case differently.
I would rather have separate routes – it’s clearer and less convoluted (IMHO).
@app.route('/feedbackform/', methods=['GET', 'POST'])
def feedback_portal():
return render_template('feedback.html', title='Inquiry Submission')
@app.route('/vo/feedbackform/', methods=['GET', 'POST'])
def feedback_portal_vo():
return render_template('feedback_vo.html', title='Inquiry Submission')
I’m attempting to create a dynamic flask route. I want to create a parallel page for my route that internal users can see when they add ‘vo/’ before the URL. So essentially there are two different routes /vo/feedbackform
and /feedbackform
. I know I could just create two routes in the app, but I’m hoping I can optimize.
@app.route('/<x>feedbackform', methods=['GET', 'POST'])
def feedback_portal(x):
if x == 'vo/':
return render_template('feedback_vo.html', title='Inquiry Submission')
elif x == '':
return render_template('feedback.html', title='Inquiry Submission')
So far, this only works when the URL using the vo/ in the x
part of the URL by my elif
isn’t working, and I get an error.
I don’t think this is supported by Flask.
For your case that you have only 2 paths to support, you can add two decorators/routes to same function and then inspect the request.path
to render the appropriate template:
from flask import request
@app.route('/vo/feedbackform', methods=['GET', 'POST'])
@app.route('/feedbackform', methods=['GET', 'POST'])
def feedback_portal():
if request.path[0:4] == '/vo/':
return render_template('feedback_vo.html', title='Inquiry Submission')
else:
return render_template('feedback.html', title='Inquiry Submission')
If you had multiple options to support instead of just /vo/
, you could look into declaring the dynamic part as path
:
@app.route('/<path:x>feedbackform', methods=['GET', 'POST'])
And add one more route to handle the static /feedbackform
.
Building off of @ilias-sp’s answer, I was able to use this code:
@app.route('/feedbackform/', methods=['GET', 'POST'], defaults={'x': None})
@app.route('/<x>/feedbackform/', methods=['GET', 'POST'])
def feedback_portal(x):
if x=='vo':
return render_template('feedback_vo.html', title='Inquiry Submission')
elif x==None:
return render_template('feedback.html', title='Inquiry Submission')
I don’t know your reasons for wanting to have a single handler but if the snippet you provided is all there is to it, I don’t see much in common between the two routes to warrant a single handler especially if you are going to use if-else to handle each case differently.
I would rather have separate routes – it’s clearer and less convoluted (IMHO).
@app.route('/feedbackform/', methods=['GET', 'POST'])
def feedback_portal():
return render_template('feedback.html', title='Inquiry Submission')
@app.route('/vo/feedbackform/', methods=['GET', 'POST'])
def feedback_portal_vo():
return render_template('feedback_vo.html', title='Inquiry Submission')