How Flask Routing Works
2015-07-11 21:31
381 查看
@How Flask Routing Works
The entire idea of Flask (and the underlying Werkzeug library) is to map URL paths to some logic that you will run (typically, the "view function"). Your basic view is defined like this:@app.route('/greeting/<name>') def give_greeting(name): return 'Hello, {0}!'.format(name)
Note that the function you referred to (add_url_rule) achieves the same goal, just without using the decorator notation. Therefore, the following is the same:
def give_greeting(name): return 'Hello, {0}!'.format(name) app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)
Let's say your website is located at 'www.example.org' and uses the above view. The user enters the following URL into their browser:
http://www.example.org/greeting/Mark
The job of Flask is to take this URL, figure out what the user wants to do, and pass it on to one of your many python functions for handling. It takes the path:
/greeting/Mark
...and matches it to the list of routes. In our case, we defined this path to go to the
give_greetingfunction.
However, while this is the typical way that you might go about creating a view, it actually abstracts some extra info from you. Behind the scenes, Flask did not make the leap directly from URL to the view function that should handle this request. It does not simply say...
URL (http://www.example.org/greeting/Mark) should be handled by View Function (the function "my_greeting")
Actually, it there is another step, where it maps the URL to an endpoint:
URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "my_greeting". Requests to Endpoint "my_greeting" should be handled by View Function "my_greeting"
Basically, the "endpoint" is an identifier that is used in determining what logical unit of your code should handle the request. Normally, an endpoint is just the name of a view function. However, you can actually change the endpoint, as is done in the following example.
@app.route('/greeting/<name>', endpoint='say_hello') def give_greeting(name): return 'Hello, {0}!'.format(name)
Now, when Flask routes the request, the logic looks like this:
URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "say_hello". Endpoint "say_hello" should be handled by View Function "my_greeting"
How You Use the Endpoint
The endpoint is commonly used for the "reverse lookup". For example, in one view of your Flask application, you want to reference another view (perhaps when you are linking from one area of the site to another). Rather than hard-code the URL, you can useurl_for(). Assume the following
@app.route('/')
def index():
print url_for('give_greeting', name='Mark') # This will print '/greeting/Mark'
@app.route('/greeting/<name>') def give_greeting(name): return 'Hello, {0}!'.format(name)
This is advantageous, as now we can change the URLs of our application without needing to change the line where we reference that resource.
Why not just always use the name of the view function?
One question that might come up is the following: "Why do we need this extra layer?" Why map a path to an endpoint, then an endpoint to a view function? Why not just skip that middle skip?The reason is because it is more powerful this way. For example, Flask Blueprints allow you to split your application into various parts. I might have all of my admin-side resources in a blueprint called "admin", and all of my user-level resources in an endpoint called "user".
Blueprints allow you to separate these into namespaces. For example...
main.py:
from flask import Flask, Blueprint from admin import admin from user import user app = Flask(__name__) app.register_blueprint(admin, url_prefix='admin') app.register_blueprint(user, url_prefix='user')
admin.py:
admin = Blueprint('admin', __name__) @admin.route('/greeting') def greeting(): return 'Hello, administrative user!'
user.py:
user = Blueprint('user', __name__) @user.route('/greeting') def greeting(): return 'Hello, lowly normal user!'
Note that in both blueprints, the '/greeting' route is a function called "greeting". If I wanted to refer to the admin "greeting" function, I couldn't just say "greeting" because there is also a user "greeting" function. Endpoints allow for a sort of namespacing by having you specify the name of the blueprint as part of the endpoint. So, I could do the following...
print url_for('admin.greeting') # Prints '/admin/greeting' print url_for('user.greeting') # Prints '/user/greeting'
Small example:
from flask import Flask, url_for app = Flask(__name__) # We can use url_for('foo_view') for reverse-lookups in templates or view functions @app.route('/foo') def foo_view(): pass # We now specify the custom endpoint named 'bufar'. url_for('bar_view') will fail! @app.route('/bar', endpoint='bufar') def bar_view(): pass with app.test_request_context('/'): print url_for('foo_view') print url_for('bufar') # url_for('bar_view') will raise werkzeug.routing.BuildError print url_for('bar_view')
相关文章推荐
- SharedPreference作用及数据操作模式
- 002-Scala函数定义、流程控制、异常处理入门实战
- 1029. 旧键盘(20)
- 学习笔记_过滤器概述(过滤器JavaWeb三大组件之一)
- eclipse android 设置及修改生成apk的签名文件
- 编译安装LAMP环境
- 【整理】常用正则表达式
- Leetcode# 36 Valid Sudoku
- Android: NDK编程入门笔记
- Dreamweaver cs6合理配色设置字体大小以提高代码阅读性
- Hiho 1014 题目
- 阅读摘要
- 【栈的应用】栈的出栈序列问题研究
- HTTP::Request
- 1028. 人口普查(20)
- SublimeText3: ImportError: No module named ‘urllib2′ 的解决办法
- 类与对象
- 二叉树的实现
- [LintCode] 最多有多少个点在一条直线上
- maven setting.xml配置说明