Custom routing in Flask app

2020-02-29 10:11发布

I've been trying to understand how to generate dynamic Flask URLs. I've read the docs and several example, but can't figure out why this code doesn't work:

path = 'foo'
@app.route('/<path:path>', methods=['POST'])
def index(path=None):
    # do some stuff...
    return flask.render_template('index.html', path=path)

I'd expect my index.html template to be served to /foo, but it is not. I get a build error. What am I missing?

If I use a fixed path, like /bar, everything works without issue.

@app.route('/bar', methods=['POST'])

标签: python flask
2条回答
▲ chillily
2楼-- · 2020-02-29 10:36

You've got the long and short of it already. All you need to do is decorate your view functions using the /<var> syntax (or the /<converter:var> syntax where appropriate).

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/<word>', defaults={'word': 'bird'})
def word_up(word):
    return render_template('whatstheword.html', word=word)

@app.route('/files/<path:path>')
def serve_file(path):
    return send_from_directory(app.config['UPLOAD_DIR'], path, as_attachment=True)

if __name__ == '__main__':
    app.debug = True
    app.run(port=9017)

When Flask pulls a variable out of a URL for a dynamic route like you're trying to use, it'll be a unicode string in Python by default. If you create the variable with the <int:var> or <float:var> converters, it'll be converted to the appropriate type in the app space for you.

The <path:blah> converter will match on a string that contains slashes (/), so you can pass /blah/dee/blah and the path variable in your view function will contain that string. Without using the path converter, flask would try and dispatch your request to a view function registered on the route /blah/dee/blah, because the plain <var> is delineated by the next / in the uri.

So looking at my little app, the /files/<path:path> route would serve whatever file it could find that matched the path sent up by the user on the request. I pulled this example from the docs here.

Also, dig that you can specify defaults for your variable URLs via a keyword arg to the route() decorator.

If you want, you can even access the underlying url_map that Werkzeug builds based on how you specify your view functions and routes in your app space. For more stuff to chew on, check out the api docs on URL registrations.

查看更多
地球回转人心会变
3楼-- · 2020-02-29 10:39

You can use add_url_rule():

def index(path=None):
    return render_template('index.html', path=path)

path = '/foo'
app.add_url_rule(path, 'index', index)

You also might want to look at blueprint objects if you end up doing this alot.

查看更多
登录 后发表回答