Flask给视图增加多个装饰器的问题及解决方案

普通方法

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

注意:用于校验session的装饰器应该放在路由的装饰器下面!

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冲突了。

看下面解决办法

方法一:为每个“路由”设置别名

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,只是为了区分。
'''

方法二:利用functools

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
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
'''

~~

 

posted on 2019-07-10 21:57  江湖乄夜雨  阅读(430)  评论(0编辑  收藏  举报