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