视图
###### 给单个视图添加装饰器 ######
# 适用场景:较少的函数中需要额外添加功能
# 注意:因为默认添加装饰器时会改变函数名(__name__), 而endpoint默认等于(__name__), 所以需要修复装饰器, 不然会报错
from functools import wraps
from flask import render_template, redirect, url_for, , session
def auth_user(func):
@wraps(func)
def inner(*args, **kwargs):
if session.get('user'):
return func(*args, **kwargs)
else:
return redirect(url_for('account.login'))
return inner
@app.route('/index/')
@auth_user
def index(nid):
return render_template('index.html')
# 源码片段
class Flask(_PackageBoundObject):
...
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
def _endpoint_from_view_func(view_func):
...
return view_func.__name__
def add_url_rule(self, rule, endpoint=None, view_func=None,
provide_automatic_options=None, **options):
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
...
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
###### 给所有视图添加装饰器 ######
# 返回None继续向下执行
@app.before_request
def auth():
if request.path == '/login/':
return None
else:
if session.get('user'):
return None
else:
return redirect(url_for('login'))
反向解析,
(适用于个别函数添加功能)
* (适用于批量)有返回值,直接返回,没有继续执行
@app.before_request
def xxx():
if request.path == '/login':
return None
if session.get('user'):
return None
return redirect(url_for('login'))
路由
路由系统本质就是url和函数对应关系
@app.route('/index/') ---> @decorator
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
----------------------------------
from flask import Flask
app = Flask(__name__)
# @app.route('/index/')
def index():
return 'Hello World!'
app.add_url_rule('/', None, index)
if __name__ == '__main__':
app.run()
# cbv
from flask import Flask, views
app = Flask(__name__)
class IndexView(views.MethodView):
def get(self, *args, **kwargs):
return 'GET'
def post(self, *args, **kwargs):
return 'POST'
app.add_url_rule('/', None, IndexView.as_view('IndexView'))
if __name__ == '__main__':
app.run()
蓝图(blueprint)
# 作用
用于给应用提供目录划分
# 定义蓝图
from flask import Blueprint
home = Blueprint('home', __name__)
# 注册蓝图
app.register_blueprint(home)
# 指定模板目录和静态文件目录
home = Blueprint('home', __name__, template_folder='', static_folder='', static_url_path='')
先去app的templates找,找不到才到指定的找
静态文件目录一样
# 给蓝图加url前缀
app.register_blueprint(home, url_prefix='/xxx')
# 给蓝图加before_request(实现局部使用装饰器)
@home.before_request
def x1():
print('1111111')
# 小蓝图
pycharm_project_874/
├── manage.py
└── small_blueprint
├── __init__.py
├── static
├── templates
└── views
# 大蓝图
pycharm_project_533/
├── big_blueprint
│ ├── admin
│ │ ├── __init__.py
│ │ ├── static
│ │ ├── templates
│ │ └── views
│ ├── __init__.py
│ └── web
│ ├── __init__.py
│ ├── static
│ ├── templates
│ └── views
└── manage.py
偏函数, 自动传递参数
from functools import partial
def func(a, b)
return a + b
new_func = partial(func, 1)
new_func(2)