Flask(五) 视图、路由

视图

###### 给单个视图添加装饰器 ######
# 适用场景:较少的函数中需要额外添加功能
# 注意:因为默认添加装饰器时会改变函数名(__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)


posted @ 2018-08-15 21:42  ret  阅读(80)  评论(0)    收藏  举报