一、函数加装饰器的执行顺序
flask的路由基于装饰器---->在视图函数上再加装饰器---->加多个装饰器的执行顺序---->登录认证装饰器---->加载router下,先做路由匹配,匹配成功执行被auth包裹的视图函数
二、路由系统
flask的路由是基于装饰器的---->但是它的本质是app.add_url_rule
方法---->类似于django的path(url)
1.转换器
app.add_url_rule(rule='/index/<string:name>',endpoint='index',view_func=index,methods=['GET'])
跟django 2.x后的转换器一样
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
2.路由系统的本质
route的源代码:
1、decorator = app.route('/',methods=['GET','POST'],endpoint='n1')
def route(self, rule, **options):
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
2、@decorator
decorator(index)
---->本质---->self.add_url_rule(rule, endpoint, f, **options)
3、路由的本质可以写成
app.add_url_rule(rule='/',endpoint='index',view_func=index,methods=['GET'])
4、endpoint如果不传,是None,也有个默认值---->函数的名字(了解)
如果使用了装饰器,一定要指定endpoint(不指定,函数名就是内层函数的名字,加多个装饰器,endpoint都是一个值导致出错)
3.app.add_url_rule参数
@app.route
和app.add_url_rule
参数:
1、rule
:URL规则
2、view_func
:视图函数内存地址
3、defaults = None
:默认值, 当URL中无参数,函数需要参数时,使用defaults = {‘k’: ‘v’} 为函数提供参数
4、endpoint = None
:名称,用于反向生成URL,即: url_for(‘名称’)
5、methods = None
:允许的请求方式,如:[“GET”, “POST”]
6、strict_slashes = None
:对URL最后的 / 符号是否严格要求
'''
@app.route('/index', strict_slashes=False)
# 访问http://www.xx.com/index/ 或http://www.xx.com/index均可
@app.route('/index', strict_slashes=True)
# 仅访问http://www.xx.com/index
'''
7、redirect_to = None
:重定向到指定地址
'''
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
'''
示例:
from flask import Flask, url_for
app = Flask(__name__)
app.debug = True # 热更新---->不停机更新
# @ 是python的语法糖(特殊语法),把下面的函数当做参数传入到装饰器函数中,把返回值再赋值给被装饰的函数
@app.route(rule='/', methods=['GET'], endpoint='index') # index=app.route()(index)
def index():
return 'hello flask'
# @app.route('/login/<string:name>',defaults={'name':'lqz'})
@app.route('/login/<string:name>')
def login(name):
# 等同于django的reverse---》url_for 反向解析(通过别名,获取url)
# print(name)
url = url_for('index')
print(url)
return 'login'
@app.route('/test', redirect_to='/')
def test():
return 'test'
# 装饰器加上,本质是----》app.add_url_rule(function=index,rule=rule,endpoint=endpoint,methods=['GET'])
# app.add_url_rule(rule='/',endpoint='index',view_func=None,methods=['GET'])
# add_url_rule--->等同于django的path('/',index,name='index')
if __name__ == '__main__':
app.run()
补充:
def add():
print('add')
# 取函数名字
print(type(add.__name__))
# python中一切皆对象,可以当成对象来赋值,取值
add.name = 'lqz'
print(add.name)
add()
4.支持正则(不用)
# 1 写类,继承BaseConverter
# 2 注册:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("\d+"):nid>') 正则表达式会当作第二个参数传递到类中
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter
app = Flask(import_name=__name__)
class RegexConverter(BaseConverter):
"""
自定义URL匹配正则表达式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
self.regex = regex
def to_python(self, value):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
"""
return int(value)
def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
"""
val = super(RegexConverter, self).to_url(value)
return val
# 添加到flask中
app.url_map.converters['regex'] = RegexConverter
@app.route('/index/<regex("\d+"):nid>')
def index(nid):
print(url_for('index', nid='888'))
return 'Index'
if __name__ == '__main__':
app.run()
5.CBV源码分析(跟django没有区别)
from flask import Flask, url_for
from flask.views import View, MethodView
app = Flask(__name__)
app.debug = True # 热更新---->不停机更新
@app.route(rule='/', methods=['GET'], endpoint='index')
def index():
return 'hello flask'
# 1 写一个类,继承MethodView
class LoginView(MethodView):
def get(self):
return 'get --login'
def post(self):
return 'post---login'
# 2 配置路由,LoginView.as_view()但是必须带一个参数,参数是这个地址的别名
app.add_url_rule('/login', view_func=LoginView.as_view('login'))
# add_url_rule--->等同于django的path('/',index,name='index')
if __name__ == '__main__':
app.run()
三、模板语法
完全兼容DTL,比DTL强大一些,可直接执行函数,还可以传参数。
循环、if、处理xss攻击(Markup等价django的mark_safe)、函数可以直接加括号执行
extends、include,和django一模一样
示例:
from flask import Flask, render_template, Markup
app = Flask(__name__