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
Related
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')
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.)
Lets say that I have the following
from flask import Flask, render_template
import config
import utils
app = Flask(__name__)
#app.route("/")
def index():
# call utils.function_foo(app)
return render_template("index.html")
#app.route("/about/")
def about():
# call utils.function_foo(app)
return render_template("about.html")
# ... more endpoint handling
if __name__ == "__main__":
app.run(debug=True)
What I want to do is perform function_foo before each routing function has a chance to return.
#app.before_request
def function_foo(app):
# Something foo'ey.
Is not the solution since this calls function_foo every time the server gets any HTTP request.
This means that if I request the about page, and it has 30 images, js files, css files, etc that it has to request, then function_foo will be called 31 times before the about page is loaded. I want function_foo to be called once in this case, not 31.
If anyone knows a thing about this, then I would greatly appreciate some information on it.
Cheers!
If you want to call a function before or after the route function, you can write your own decorator.
It seams that you don't really want that:
What I want to do is perform function_foo before each routing function has a chance to return.
If you want to call function_foo before the rendering, you can write your own rendering function:
def my_rendering(*args, **kwargs):
function_foo()
return render_template(*args, **kwargs)
in Flask Framework, define a route
#main.route('/')
def index():
return render_template('index.html')
only can you use get method to request the index.html.
if I try to post some data to the index.html.
I got a method not allow webpage return. and that's correct.
but my problem is, Is there anyway I can customize the page by myself?
for example, return json data, instead of a method not allowed webpage??
You can create error handler
from flask import jsonify
#app.errorhandler(405)
def method_not_allowed(e):
return jsonify({'error': 405}), 405
http://flask.pocoo.org/docs/0.10/patterns/errorpages/
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)