Creating dynamic flask route - python

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.

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 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.

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')

Related

Flask-wtforms Redirect on Form Submission and Pass Variables

I am struggling to figure out why I am unable to pass variables to my redirected url. I have attempted the suggestions in the following questions, but for some reason they are not working.
redirect while passing arguments
How can I pass arguments into redirect(url_for()) of Flask?
The only thing I can think of is that it is because I am using flask-wtforms to validate the form before the redirect. I haven't seen much in way of answers/suggestions for this scenario. So here I am.
#app.route('/quiz/', methods=['GET', 'POST'])
def quiz():
form = Quiz()
if form.validate_on_submit():
q1_answer = 'North'
return redirect(url_for('result', q1_answer=q1_answer))
return render_template('quiz.html', form=form)
#app.route('/result/', methods=['GET', 'POST'])
def result():
q1_correct_answer = request.args.get('q1_answer')
return render_template('result.html', q1_correct_answer=q1_correct_answer)
The redirect works the way it should. The 'result' url and its corresponding template are rendered. I just can't get the variable (q1_answer) to pass. My template always returns a value of None. Any help would be greatly appreciated.
I think you use it
#app.route('/quiz/', methods=['GET', 'POST'])
def quiz():
form = Quiz()
if request.method == "POST" and form.validate_on_submit():
q1_answer = 'North'
return redirect(url_for('result', q1_answer=q1_answer))
return render_template('quiz.html', form=form)
#app.route('/result/', methods=['GET', 'POST'])
def result(q1_answer):
return render_template('result.html', q1_correct_answer=q1_answer)

How to convert POST request to GET request in flask?

I created a web application in flask that has a form and whatever text the user enters appears on the bottom along with all the previously entered messages.
I was trying to load test it using JMeter, but I'm not able to send POST request using multiple threads in JMeter so I wanted to convert the post request to GET request so that I am able to perform load tests on my application.
Currently my route looks something like this
#app.route('/blog', methods=['GET', 'POST'])
#app.route('/', methods=['GET', 'POST'])
def blog():
print
form = PostForm()
if form.validate_on_submit():
post = Post(body=form.post.data)
db.session.add(post)
db.session.commit()
return redirect(url_for('blog'))
posts = Post.query.all()
return render_template('index.html', title='Blogger', form=form,
posts=posts)
What can I do to send the parameters through the URL.
I am very new to web development and I followed the mega tutorial in flask. Is there a workaround this?
add #app.route("/<string:param>",methods['GET']) and give it default values def blog(param = "") and use it for your get method
#app.route("/<string:param>",methods['GET'])
#app.route("/blog/<string:param>",methods['GET'])
#app.route('/blog', methods=['GET', 'POST'])
#app.route('/', methods=['GET', 'POST'])
def blog(param = ""):
print
if request.method == "POST":
##your post code here
elif request.method == "GET":
## new code using 'param' here

same url_prefix for two flask blueprints

I want to implement simple site layout:
/ must render home.html
/one, /two, /three must render one.html, two.html, three.html correspondingly
So far I came up with following code:
main_page = Blueprint('main', __name__)
category_page = Blueprint('category', __name__)
#main_page.route("/")
def home():
return render_template('home.html')
#category_page.route('/<category>')
def show(category):
return render_template('{}.html'.format(category))
app = Flask(__name__)
app.register_blueprint(main_page, url_prefix='/')
app.register_blueprint(category_page, url_prefix='/categories')
This way I am able to route categories to /categories/<category>. How can I route them to just /<category> instead, while keeping home.html linked to /? Appreciate your help
I tried two approaches:
Setting url_prefix='/' for both blueprints => second one does not work.
Instead of main_page blueprint use just app.route('/') to render home.html. This one also does not work when mixing with category_page blueprint
You can move the variable to the url_prefix parameter inside the registering statement :
#main_page.route("/")
def home():
return render_template('home.html')
app.register_blueprint(main_page, url_prefix='/')
#category_page.route('/')
def show(category):
return render_template('{}.html'.format(category))
app.register_blueprint(category_page, url_prefix='/<category>')
(it depends on the complexity of the whole pattern, but it may be better to keep the registering statements with the variables close to each function to handle many views.)

Flask - Pass data from different functions to same template

So basically I have two functions
#app.route('/index', methods=['GET'])
def do_stuff1():
*LOGIC*
return (render_template('index.html', data=data))
and
#app.route('/index', methods=['GET'])
def do_stuff2():
*LOGIC*
return (render_template('index.html', moreData=moreData))
How do I pass through the data from the second function to the the same template because it's not working as I have specified there. I'm only getting the first functions data.
EDIT: I should have specified that I want to use the data within the same route.
Your second function does not have to be a 'view' but just a plain python function. Unless I'm missing something...
#app.route('/index', methods=['GET'])
def do_stuff1():
*LOGIC*
moreData = do_stuff2()
return render_template('index.html', data=data, moreData=moreData)

How to have an alias of URL on Python Flask?

I'm using Flask 0.8.
How to have an alias of a URL like this:
#app.route('/')
def index():
# I want to display as http://localhost/index, BUT, I DON'T WANT TO REDIRECT.
# KEEP URL with only '/'
#app.route('/index')
def index():
# Real processing to display /index view
So, why my hope to use an alias because of DRY of processing /index
Someone knew the solution?
thanks pepperists.
This should work. But why do you want two URL's to display the same thing?
#app.route('/')
#app.route('/index')
def index():
...
As is written in URL registry doc of Flask :
You can also define multiple rules for the same function. They have to
be unique however.
#app.route('/users/', defaults={'page': 1})
#app.route('/users/page/<int:page>')
def show_users(page):
pass
I don't know if Flask has a way to assign more than one URL to a view function, but you could certainly chain them like this:
#app.route('/')
def root():
return index()
#app.route('/index')
def index():
# Real processing to display /index view

Categories

Resources