两种写法
from flask import Flask
app = Flask(__name__)
# 方法1:
# @app.route('/index')
def index():
return 'index'
# 方法2:
app.add_url_rule('/index', view_func=index)
if __name__ == '__main__':
app.run()
源码分析:
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
# 第一步
app.route = app.decorator
# 第二步
route('/index') = decorator('/index')
# 第三步
app.add_url_rule('/index', endpoint=None, func)
endpoints 重名报错
源码:
def add_url_rule(self, rule, endpoint=None, view_func=None,
provide_automatic_options=None, **options):
if endpoint is None:
# endpoint默认为函数名
endpoint = _endpoint_from_view_func(view_func)
###################################################################
# 被调用函数
def _endpoint_from_view_func(view_func):
"""Internal helper that returns the default endpoint for a given
function. This always is the function name.
"""
assert view_func is not None, 'expected view func if endpoint ' \
'is not provided.'
return view_func.__name__
####################################################################
options['endpoint'] = endpoint
if view_func is not None:
# 获取已存在的endpoint对应的func
old_func = self.view_functions.get(endpoint)
# 若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)
route参数
@app.route和app.add_url_rule参数:
rule
# URL规则
view_func
# 视图函数名称
defaults=None
# 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
endpoint=None
# 名称,用于反向生成URL,即: url_for('名称')
methods=None
# 允许的请求方式,如:["GET","POST"]
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
redirect_to=None,
# 重定向到指定地址,如:
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
或
def func(adapter, nid):
return "/home/888"
@app.route('/index/<int:nid>', redirect_to=func)
subdomain=None,
# 子域名访问
from flask import Flask, views, url_for
app = Flask(import_name=__name__)
app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
@app.route("/", subdomain="admin")
def static_index():
"""Flask supports static subdomains
This is available at static.your-domain.tld"""
return "static.your-domain.tld"
@app.route("/dynamic", subdomain="<username>")
def username_index(username):
"""Dynamic subdomains are also supported
Try going to user1.your-domain.tld/dynamic"""
return username + ".your-domain.tld"
if __name__ == '__main__':
app.run()
CBV
from flask import Flask, views
app = Flask(__name__)
def wrapper(func):
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner
class UserView(views.MethodView):
# methods = ['GET']
decorators = [wrapper,] # 可以添加装饰器函数,调用get和post方法时会自动调用
def get(self, *args, **kwargs):
return 'GET'
def post(self, *args, **kwargs):
return 'POST'
app.add_url_rule('/user',None,UserView.as_view('user_list'))
if __name__ == '__main__':
app.run()
自定义正则
@app.route('/user/<username>')
@app.route('/post/<int:post_id>')
@app.route('/post/<float:post_id>')
@app.route('/post/<path:path>')
@app.route('/login', methods=['GET', 'POST'])
常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
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):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
:param value:
:return:
"""
return int(value)
def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
:param value:
:return:
"""
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()