Flask初探二( app.route 内部实现)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask初探二( app.route 内部实现)相关的知识,希望对你有一定的参考价值。
参考技术A上一篇blog 探究了flask 各个参数的作用,本篇将围绕 @app.route(\'/\') 探究一下flask 做了些什么
route 源码
route 实际上是一个闭包, 路径规则通过route 方法被rule 形参引用, 然后返回decorator 方法,所以@app.route(\'/\') <==>@decorator , 所以 hello_world =decorator (hello_world ) <==> hello_world .
@app.route(\'/\') 的主要作在于 endpoint = options.pop(\'endpoint\', None) 和 self.add_url_rule(rule, endpoint, f, **options) 两句.
add_url_rule 源码
从方法注释可以看到另外一种可以将url 规则和试图函数绑定的方式
通过装饰器注册路由, 一般情况下 endpoint 等于None, 所以endpoint = _endpoint_from_view_func(view_func).
_endpoint_from_view_func
通过查看_endpoint_from_view_func方法, 可以知道endpoint = view_func.__name__, 既通过装饰器注册路由,一般情况下 endpoint 等于方法名.
实验
一般情况下 view_func 是没有methods 属性的, 通过修改源码方便实验
源码
demo.py
实验结果
通过上面的结果可以看出
分析
通过这两句可以得出一个结论, methods 通过键值对形式赋值, 除了methods = "POST" 的形式之外的所有可迭代的容器都可以作为值.
源码
实验
源码改造
demo.py
结果
通过实验可以得出,
源码
实验
源码改动
demo.py
实验结果
总结:
到此结 DragonFangQy 2018.6.20
Flask 学习之 路由
一.路由的基本定义
# 指定访问路径为 demo1
@app.route(‘/demo1‘)
def demo1():
return ‘demo1‘
二.常用路由设置方式
@app.route(‘/user/<username>‘) #常用的 不加参数的时候默认是字符串形式的
@app.route(‘/post/<int:post_id>‘) #常用的 #指定int,说明是整型的
@app.route(‘/post/<float:post_id>‘)
@app.route(‘/post/<path:path>‘)
@app.route(‘/login‘, methods=[‘GET‘, ‘POST‘])
三.路由可以设置传递参数, 2种方式
1.一种为路由传递参数[没有限定类型]
2.路由传递参数[限定数据类型]
以下为相应的例子:
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = "hsz" from flask import Flask app = Flask(__name__) # 加载项目配置 # 配置类 class Config(object): DEBUG = True app.config.from_object(Config) # 路由传递参数[没有限定类型] @app.route(‘/user/<user_id>‘) def user_info_1(user_id): return ‘hello info_1 %s‘ % user_id # 路由传递参数[限定数据类型],列子是用了int类型,可以选择bool,float都可以的 # user_id 必须是整数 @app.route(‘/user/<int:user_id>‘) def user_info_2(user_id): return ‘hello info_2 %d‘ % user_id if __name__ == ‘__main__‘: app.run(host=‘127.0.0.1‘, port=9000) """ 测试说明: 测试1: http://127.0.0.1:9000/user/qwer 这样的情况是访问了函数1的url,因为qwerb不为整数,所以路由到没有限定类型处 测试2: http://127.0.0.1:9000/user/2 这样的情况下会选择有限定类型的路由 测试3: 注释限定的,让后使用如下url测试: http://127.0.0.1:9000/user/2 这样会走无限定的路由 """
四.路由之url_for()函数
1.给指定的函数构造URL
#例1: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = "hsz" from flask import Flask, url_for from flask import redirect app = Flask(__name__) @app.route(‘/index‘) # endpoint是别名 def home(): """ url_for是个函数接受视图函数的名字(字符串形式)作为参数,返回视图函数对应的url 通过url_for home 来获取前端输入的url是什么 :return: """ v = url_for("home") print(v) return "index" # url_for() 使用endpoint ,通过反向机制构建URL路径 @app.route(‘/index/<int:nid>‘, endpoint="aaa") # endpoint是别名 def zzz(nid): """ 这边使用了别名,将zzz函数别名为aaa 所以url_for 对的是aaa :param nid: :return: """ v = url_for("aaa", nid=nid) print(v) return "index2" if __name__ == ‘__main__‘: app.run(host=‘127.0.0.1‘, port=9000)
2.访问静态文件(CSS / JavaScript 等)
只要在你的包中或是模块的所在目录中创建一个名为 static 的文件夹,在应用中使用 /static 即可访问。
url_for(‘static‘, filename=‘style.css‘)
这个文件应该存储在文件系统上的 static/style.css
五.路由的正则匹配方式
1.自定义转换器实现
在 web 开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,根据自己的规则去限定请求参数再进行访问
具体实现步骤为:
(1)导入转换器基类:在 Flask 中,所有的路由的匹配规则都是使用转换器对象进行记录
(2)自定义转换器:自定义类继承于转换器基类
(3)添加转换器到默认的转换器字典中
(4)使用自定义转换器实现自定义匹配规则
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = "hsz" # 下面编写一个自定义路由转换器 from flask import Flask app = Flask(__name__) # 导入转换器基类 from werkzeug.routing import BaseConverter class MobileNumberConverter(BaseConverter): """ 手机号码的自定义路由转换器 """ regex = "d{11}" # 添加转换器到默认的转换器字典中,并指定转换器使用时名字为: mobile app.url_map.converters[‘mobile‘] = MobileNumberConverter # 使用转换器去实现自定义匹配规则 @app.route(r"/sms/<mobile:mobile_number>/") # mobile_number就是测试的电话号码 def sms(mobile_number): """ 通过以下url访问: http://127.0.0.1:9000/sms/13666666666/ :param mobile_number: :return: """ print(mobile_number) return "手机号通过,短信" # 例2 class RegexConverter(BaseConverter): """正在路由转换器""" def __init__(self, url_map, *args): # super().__init__(url_map) # 或者这样写 # url_map 所有url组成的元组 super(RegexConverter, self).__init__(url_map) # 初始化分类 self.regex = args[0] # 是一个元组 app.url_map.converters[‘reg‘] = RegexConverter # w 表示大写字母小写字母下划线 @app.route(r"/register/<reg(‘w{4,6}‘):username>/") def reg(username): # 这个函数名没有限制 """ 通过以下url访问: http://127.0.0.1:9000/register/qwer/ :param username: :return: """ print(username) return "ok reg" if __name__ == "__main__": app.run(host=‘0.0.0.0‘, port=9000)
2.系统自带转换器
在werkzeug.routing.py源文件中
DEFAULT_CONVERTERS = { "default": UnicodeConverter, "string": UnicodeConverter, "any": AnyConverter, "path": PathConverter, "int": IntegerConverter, "float": FloatConverter, "uuid": UUIDConverter, }
以上类型都是系统自带的。
系统自带的转换器具体使用方式在每种转换器的注释代码中有写,请留意每种转换器初始化的参数。
以上是关于Flask初探二( app.route 内部实现)的主要内容,如果未能解决你的问题,请参考以下文章