一:问题:添加多个装饰器,抛异常
在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
'''