1. 引言
问题:使用含session判断的装饰器给至少2个视图函数校验用户是否登录。
常规操作:
- 先写session校验某个视图函数登录
- 再用session校验所有视图函数
1.先写session校验某个视图函数登录:
单独给index视图函数添加上limits装饰器:
from flask import Flask,session,request,render_template,redirect
app = Flask(__name__)
app.secret_key = "winstonfyMD5"
def limits(func):
def inner(*args,**kwargs):
if session.get("user"):
ret = func(*args,**kwargs)
return ret
else:
return redirect("/login")
return inner
@app.route('/')
@limits
def index():
return render_template("index.html")
@app.route('/login',methods=["GET","POST"])
def login():
if request.method == "GET":
return render_template("login.html")
else:
session["user"] = request.form.get("username")
return redirect("/")
@app.route('/detail')
def detail():
return render_template("detail.html")
if __name__ == "__main__":
app.run(debug=True)
没问题,limits装饰器可以限制用户对index视图函数的访问
2.再用session校验所有视图函数
给detail视图函数也添加上limits装饰器
@app.route('/detail')
@limits
def detail():
return render_template("detail.html")
AssertionError:View function mapping is overwriting an existing endpoint function: inner
报错的原因需要深入到Flask的源码中一探究竟:
在pycharm中按住Ctrl
的同时点击route
:在注释中找到下面这句话
:param endpoint:
the endpoint for the registered URL rule. Flask itself assumes the name of the view function as endpoint
endpoint
负责路由的反向解析,endpoint
在默认情况下就是视图函数名
报错原因:在使用装饰器的时候,我们的index函数
与detail函数
最后实际上都是在执行同一个inner函数
,这种情况下就导致了endpoint
冲突,从而无法判断到底是哪个路由
解决办法:只要index函数
与detail函数
的endpoint
不同就不会产生冲突
@app.route('/',endpoint="index")
@limits
def index():
return render_template("index.html")
@app.route('/detail',endpoint="detail")
@limits
def detail():
return render_template("detail.html")
通过上述事例得知,要想应用好Flask,就必须彻底弄懂Flask中的路由系统
2. 路由参数介绍
@app.route() 装饰器中的参数
methods : 当前 url 地址,允许访问的请求方式
@app.route('/login',methods=["GET","POST"])
def login():
if request.method == "GET":
return render_template("login.html")
else:
session["user"] = request.form.get("username")
return redirect("/")
endpoint : 反向url地址,默认为视图函数名 (url_for)
defaults : 视图函数的参数默认值{“name”:“winstonfy”}
@app.route('/get_name',endpoint="get_name",defaults={"name":"winstonfy"})
def get_name(name):
print(name)
return "ok"
strict_slashes : url地址结尾符"/"的控制 False : 无论结尾 “/” 是否存在均可以访问 , True : 结尾必须不能是 “/”
# 访问地址 : /info
@app.route("/info", strict_slashes=True)
def student_info():
return "每有悲苦不幸,最有效的安慰即是观察他人之不幸尤甚于我,此法人人可行。但就人类整体的不幸而言,这又有什么意义?"
# 访问地址 : /infos or /infos/
@app.route("/infos", strict_slashes=False)
def student_infos():
return "越是清楚地觉察到万物脆弱、虚无和梦幻般的特点,你越会清晰地觉察到自己内部存在的不朽,因为上述特点有此映衬方显鲜明,正如要觉察轮船行驶的速度,只能去看静止的河岸,而不是看轮船本身。"
redirect_to : url地址重定向
# 访问地址 : /info 浏览器跳转至 /infos
@app.route("/info", strict_slashes=True, redirect_to="/infos")
def student_info():
return "把时间花在阅读上,从书中获取智慧,就像从旅游手册上了解某个国家一样,人们可以得到很多事物的信息,但归根结底,他们对那个国家是什么样子却没有真切、明确、彻底的了解。相反,把时间花在思考上则像亲自造访一个国家,他们熟悉该国,对它有真切的认识,身处其中如鱼得水。"
@app.route("/infos", strict_slashes=False)
def student_infos():
return "诗人用意象来展示自己的想象,意象来自生活、人的性格或境遇。他们调动意象,让意象尽可能占据读者的心灵。故而,虽然贤愚殊途、才具迥异,人皆受诗人吸引。相反,哲学家展示的不是生活本身,而是从生活中提取的完成了的思想,因此要求读者也能如己一般严密而深入地思考。惟其如此,哲学的读者少之又少。诗人好比示人以花朵,哲人好比示人以花香。"
动态参数路由
from flask import url_for
# 访问地址 : http://127.0.0.1:5000/info/1
@app.route("/info/<int:nid>", methods=["GET", "POST"], endpoint="r_info")
def student_info(nid):
print(url_for("r_info",nid=2)) # /info/2
return f"Winstonfy{nid}" # Python3.6的新特性 f"{变量名}"
int:nid 就是在url后定义一个参数接收,下面是参数的类型
但是这种动态参数路由,在url_for的时候,一定要将动态参数名+参数值添加进去,否则会抛出参数错误的异常
路由正则
一般不用,如果有特殊需求,不怕麻烦的话,这个东西还是挺好用的,前提是你的正则玩儿的很6