flask_之URL
URL篇
在分析路由匹配过程之前,我们先来看看 flask 中,构建这个路由规则的两种方法:
通过
@app.route()decorator通过
app.add_url_rule,这个方法的签名为add_url_rule(self, rule, endpoint=None, view_func=None, **options),参数的含义如下:rule: url 规则字符串,可以是静态的/path,也可以包含/endpoint:要注册规则的 endpoint,默认是view_func的名字view_func:对应 url 的处理函数,也被称为视图函数
这两种方法是等价的,也就是说:
@app.route('/')
def hello():
return "hello, world!"
也可以写成
def hello():
return "hello, world!" app.add_url_rule('/', 'hello', hello)
其实,还有一种方法来构建路由规则——直接操作 app.url_map 这个数据结构。不过这种方法并不是很常用,因此就不展开了
静态路由
@app.route('/')
def hello_world():
# 变量可以通过赋值传到前端,前端可以通过Jinja语法{{}}渲染
return render_template('t1.html', name='t1', age=16)
@app.route('/services')
def services():
return 'Services'
@app.route('/about')
def about():
return 'About'
# 相对projects解释类似于文件夹解释形式,指向某一个文件夹下的某个文件
@app.route('/projects/')
@app.route('/projects_our') # 可以定义多个URL到同一个视图函数上,Flask支持
def projects():
return 'Projects'
@app.route('/login',methods=["GET","POST"])
def login():
return render_template('login.html', req_method=request.method)
动态路由
# 动态路由
@app.route('/user/<username>')
def user(username):
print username
return username # 路由转换器:指定参数类型
# flask提供3种:int(整形)|float(浮点型)|path(路径,并支持一个/)
@app.route('/user/<int:user_id>')
def user(user_id):
print user_id
return 'User_id:%s'%user_id
自定义路由规则
# flask不提供正则表达的形式的URL匹配
# 可通过定义完成
# 1、from werkzeug.routing import BaseConverter
# 2、自定义类
#转换器
class RegexConverter(BaseConverter):
def __init__(self,url_map,*items):
super(RegexConverter,self).__init__(self)
# print items # (u'[a-z]{3}[A-Z]{3}',)
# print url_map # URL 的一个MAP对象,类似路由表
self.regex = items[0] # 3、要将定义的类注册到APP的url_map中,定义名称
# app.url_map.converters['regex'] = RegexConverter # 4、使用
@app.route('/user/<regex("[a-z]{3}[A-Z]{3}"):username>')
def user(username):
print username
return 'Username:%s' % username
浅析源码
注册路由规则的时候,flask 内部做了哪些东西呢?我们来看看 route 方法:
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage.
""" def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f return decorator
route
route 方法内部也是调用 add_url_rule,只不过在外面包了一层装饰器的逻辑,这也验证了上面两种方法等价的说法
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
"""Connects a URL rule. Works exactly like the :meth:`route`
decorator. If a view_func is provided it will be registered with the
endpoint.
"""
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options['endpoint'] = endpoint
methods = options.pop('methods', None) # if the methods are not given and the view_func object knows its
# methods we can use that instead. If neither exists, we go with
# a tuple of only ``GET`` as default.
if methods is None:
methods = getattr(view_func, 'methods', None) or ('GET',)
if isinstance(methods, string_types):
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
methods = set(item.upper() for item in methods) # Methods that should always be added
required_methods = set(getattr(view_func, 'required_methods', ())) # starting with Flask 0.8 the view_func object can disable and
# force-enable the automatic options handling.
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None) if provide_automatic_options is None:
if 'OPTIONS' not in methods:
provide_automatic_options = True
required_methods.add('OPTIONS')
else:
provide_automatic_options = False # Add the required methods now.
methods |= required_methods rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if old_func is not None and old_func != view_func:
raise AssertionError('View function mapping is overwriting an '
'existing endpoint function: %s' % endpoint)
self.view_functions[endpoint] = view_func
add_url_rule
上面这段代码省略了处理 endpoint 和构建 methods 的部分逻辑,可以看到它主要做的事情就是更新 self.url_map 和 self.view_functions 两个变量。找到变量的定义,发现 url_map 是 werkzeug.routeing:Map 类的对象,rule 是 werkzeug.routing:Rule 类的对象,view_functions 就是一个字典。这和我们之前预想的并不一样,这里增加了 Rule 和 Map 的封装,还把 url 和 view_func 保存到了不同的地方。
需要注意的是:每个视图函数的 endpoint 必须是不同的,否则会报 AssertionError。
未完待续。。。
flask_之URL的更多相关文章
- HTML URL地址解析
通过JavaScript的location对象,可获取URL中的协议.主机名.端口.锚点.查询参数等信息. 示例 URL:http://www.akmsg.com/WebDemo/URLParsing ...
- URL安全的Base64编码
Base64编码可用于在HTTP环境下传递较长的标识信息.在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式.此时,采用Base64编码不仅比较简短,同时也具有不可 ...
- Android业务组件化之URL Scheme使用
前言: 最近公司业务发展迅速,单一的项目工程不再适合公司发展需要,所以开始推进公司APP业务组件化,很荣幸自己能够牵头做这件事,经过研究实现组件化的通信方案通过URL Scheme,所以想着现在还是在 ...
- ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系
ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...
- Node.js:path、url、querystring模块
Path模块 该模块提供了对文件或目录路径处理的方法,使用require('path')引用. 1.获取文件路径最后部分basename 使用basename(path[,ext])方法来获取路径的最 ...
- angular2系列教程(十一)路由嵌套、路由生命周期、matrix URL notation
今天我们要讲的是ng2的路由的第二部分,包括路由嵌套.路由生命周期等知识点. 例子 例子仍然是上节课的例子:
- MVC通过路由实现URL重写
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Ro ...
- 【转】java通用URL接口地址调用方式GET和POST方式
java通用URL接口地址调用方式GET和POST方式,包括建立请求和设置请求头部信息等等......... import java.io.ByteArrayOutputStream; import ...
- linux字符串url编码与解码
编码的两种方式 echo '手机' | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g' echo '手机' |tr -d '\n' |od -An -tx ...
随机推荐
- Codeforces Round #394 (Div. 2) C. Dasha and Password —— 枚举
题目链接:http://codeforces.com/problemset/problem/761/C C. Dasha and Password time limit per test 2 seco ...
- 图片预览JavaScript方法
实现要点 ● 对于 Chrome.Firefox.IE10 使用 FileReader 来实现. ● 对于 IE6~9 使用滤镜 filter:progid:DXImageTransform.Mi ...
- linux应用之perl环境的安装(centos)
1.安装Perl环境 yum install perl*这个命令基本上把perl的模块给安装齐了.yum install cpanCPAN这个就不用说了吧,大家都懂. 如果你对perl模块版本要求比较 ...
- 如何修改Windows的默认安装路径
运行中输入regedit打开注册表编辑器 展开注册表“HKEY_LOCAL_MACHINE\Software\Microsoft\ Windows\ CurrentVersion”分支, 在窗口的右侧 ...
- poj2828 Buy Tickets——倒序处理
题目:http://poj.org/problem?id=2828 这题可以倒序来做,因为越靠后的人实际上优先级越高: 用0和1表示这个位置上是否已经有人,0表示有,1表示没有,这样树状数组维护前缀和 ...
- 【Boost】boost库asio详解2——io_service::run函数无任务时退出的问题
io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁. void test_asio_nowork() { boost::asi ...
- py-day17-jquery
jquery实现案例 案例: 1.点赞 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- Flutter实战视频-移动电商-07.Dio基础_POST请求的使用
07.Dio基础_POST请求的使用 越界问题解决 容器越界的问题,越界是因为键盘弹起的问题.如果键盘不弹起是不会越界 我们加一个滚动组件就可以解决. 这是技术胖视频中出现的越界的截图效果 这是我自己 ...
- 5-1条件运算符 & 5-2
三目运算符 新建类: ConditionDemo 用三目运算符: package com.imooc.operator; public class ConditionDemo { public sta ...
- Mac中自定义文件夹中文名
在OSX系统中,我们打开finer,就会看到很多中文名的文件夹,比如“应用程序”.“桌面”等等,而在系统中都是以英文命名的.我们也可以自己去设置中文名. 首先需要找到设置中文的字符串资源文件,路径是/ ...