Flask--视图增加多装饰器

Posted quantum-world

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask--视图增加多装饰器相关的知识,希望对你有一定的参考价值。

一:问题:添加多个装饰器,抛异常

在Flask中如果按照普通的方法加装饰器,看上去是没有问题。他会抛出一个异常

from flask import Flask, render_template, redirect, request, session

app = Flask(__name__)
app.debug = True
app.secret_key = '123'

@app.route('/')
def home():
    return 'hello word'

def wapper(func):
    def inner(*args, **kwargs):
        if session.get('user'):
            return func()
        else:
            return redirect('/login')
    return inner

@app.route('/index')
@wapper
def index():
    return render_template('index.html')


@app.route('/rebak')
@wapper
def rebak():
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    user = request.form.get('username')
    pwd = request.form.get('pwd')
    if user == '123' and pwd == '123':
        session['user'] = user
        return render_template('index.html')


if __name__ == '__main__':
    app.run()

技术图片

标注的地方。翻译过来:AssertionError:视图函数映射覆盖现有端点函数inner

说白了。就是多个inner冲突了。


二:解决办法

2.1:方法一

from flask import Flask, render_template, redirect, request, session

app = Flask(__name__)  # 实例化flask对象
app.debug = True  # 能够随时更改自动重启,不加的话每次更改代码需要手动重启
app.secret_key = '123'  # secret_key,用于给session加密


def wapper(func):
    def inner(*args, **kwargs):
        if session.get('user'):
            return func()
        else:
            return redirect('/login')

    return inner


@app.route('/', endpoint='4')
@wapper
def home():
    return 'hello word'


@app.route('/index', endpoint='1')
@wapper
def index():
    return render_template('index.html')


@app.route('/rebak', endpoint='2')
@wapper
def rebak():
    return render_template('index.html')


@app.route('/login', methods=['GET', 'POST'], endpoint='3')  # endpoint是url的别名,相当于django中Url的name,必须写一个可迭代对象
def login():
    if request.method == 'GET':
        return render_template('login.html')
    user = request.form.get('username')
    pwd = request.form.get('pwd')
    if user == '123' and pwd == '123':
        session['user'] = user
        return render_template('index.html')


if __name__ == '__main__':
    app.run()

'''
如果给一个视图函数增加装饰器,应该加在app.route下面,这样的效果就是,
装饰器将下面的所有内容包裹,然后路由对应到这大的包裹中来。
需要注意endpoint要注明,如果不注明endpoint则默认用函数名来定义,
此时所有的函数名都叫inner了,所以需要注明endpoint,只是为了区分。
'''

2.2:方法二

from flask import Flask, render_template, redirect, request, session

app = Flask(__name__)
app.debug = True
app.secret_key = '123'

@app.route('/')
def home():
    return 'hello word'

import functools
def wapper(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        if session.get('user'):
            return func()
        else:
            return redirect('/login')
    return inner

@app.route('/index')
@wapper                                     # index = wapper(index)
def index():
    return render_template('index.html')


@app.route('/rebak')
@wapper
def rebak():
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    user = request.form.get('username')
    pwd = request.form.get('pwd')
    if user == '123' and pwd == '123':
        session['user'] = user
        return render_template('index.html')


if __name__ == '__main__':
    app.run()
'''
这个方法利用的是装饰器的修复技术,
返回的结果是每个函数的名字。
如果不加functools这个装饰器的话,每个函数都是inner
用来区分每个inner
'''

以上是关于Flask--视图增加多装饰器的主要内容,如果未能解决你的问题,请参考以下文章

装饰器的顺序在 Flask 视图中是不是重要?

如何将装饰器应用于每个 Flask 视图

Flask 给视图函数增加装饰器

11Flask实战第11天:视图使用装饰器

flask中路由,实例化配置,对象配置,特殊装饰器

python-flask复习—— 装饰器的坑及解决办法flask中的路由/实例化配置/对象配置/蓝图/特殊装饰器(中间件重定义错误页面)