flask基础2
一个装饰器无法装饰多个函数的解决方法
当我们想在flask的多个视图函数前添加同一个装饰器时,如果什么都不做会报一个错
AssertionError: View function mapping is overwriting an existing endpoint function: nei
from flask import Flask, redirect, render_template, request, session app = Flask(__name__) app.secret_key = "12345" def wai(func): def nei(*args, **kwargs): if session.get("user"): ret = func(*args,**kwargs) return ret else: return redirect("/login") return nei @app.route("/") @wai def index(): return render_template("index2.html") @app.route("/qqq") @wai def qqq(): return render_template("qqq.html") @app.route("/login", methods=["POST", "GET"]) def login(): if request.method == "GET": return render_template("login.html") else: if request.form.get("username") == "12345" and request.form.get("password") == "12345": session["user"] = request.form.get("username") return "登录成功" app.run(debug=True)
会报上面的错,原因是用装饰器去装饰函数时返回的是nei这个函数,也就是有两个nei函数,所以报错
解决方案1
import functools #引入一个函数工具 def wai(func): @functools.wraps(func) #加上这句就会保留原来的函数名 def nei(*args, **kwargs): if session.get("user"): ret = func(*args,**kwargs) return ret else: return redirect("/login") return nei
解决方案2
因为是flask视图函数,所以它为我们准备了一个参数endpoint 它反向生成url地址标志,默认视图函数名 @app.route("/", endpoint="index") @app.route("/qqq", endpoint="qqq")
1.flask中的路由
1.endpoint 反向生成url地址标志 默认视图函数名 可以from flask import url_for url_for("")
2.methods 视图函数允许的请求方式
@app.route("/login", methods=["GET", "POST"]) #默认下面的函数只有get请求,一旦添加了methods参数就会按照添加的请求方式处理,后面是一个可迭代对象列表或元组
3.动态路由参数
@app.route("/login/<string:nid>", methods=["GET", "POST"], strict_slashes=False) #<string:nid>只有string或int类型,不写就是string 有动态路由参数下面的函数必须接受参数 def index2(nid): print(url_for("index2")) print(nid) return "456"
4.defaults={"nid":"123456"} 默认参数
5.strict_slashes=True 是否严格遵循路由地址 不写就是false
6.redirect_to="/login" 永久重定向 301 #进入视图之前
2.flask实例化配置
app = Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/static")
1.template_folder="temp" 默认模板路径 templates 2.static_folder="static", 默认静态文件路径 static 3.static_url_path="/static" 访问静态文件路由地址 默认是"/"+static_folder 4.static_host=None 指定静态文件服务器地址 5.host_matching = False, # 如果不是特别需要的话,慎用,否则所有的route 都需要host=""的参数 6.subdomain_matching = False, # 理论上来说是用来限制SERVER_NAME子域名的,但是目前还没有感觉出来区别在哪里 7.instance_path = None, # 指向另一个Flask实例的路径 8.instance_relative_config = False # 是否加载另一个实例的配置 9.root_path = None # 主模块所在的目录的绝对路径,默认项目目录
3.flask对象配置
'DEBUG': False, # 是否开启Debug模式 'TESTING': False, # 是否开启测试模式 'SECRET_KEY': None # 在启用Flask内置Session的时候/开启flash,一定要有它 'PERMANENT_SESSION_LIFETIME': 31, # days , Session的生命周期(天)默认31天 'SESSION_COOKIE_NAME': 'session', # 在cookies中存放session加密字符串的名字
#配置方式1 app.config["DEBUG"] = True
#配置方式2 FlaskSetting.py -------------------------------------- class FlaskDebug(object): DEBUG = True SECRET_KEY = "LIANNDA" PERMANENT_SESSION_LIFETIME = 7 SESSION_COOKIE_NAME = "debug_session" class FlaskTesting(object): DEBUG = True SECRET_KEY = "LIANNDA" PERMANENT_SESSION_LIFETIME = 15 SESSION_COOKIE_NAME = "test_session" ----------------------------------------------------------------
import FlaskSetting app.config.from_object(FlaskSetting.FlaskDebug) app.config.from_object(FlaskSetting.FlaskTesting)
4.flask蓝图(蓝图配置)
Blueprint 当成一个不能被启动的 app Flask示例
# 蓝图配置 from flask import Blueprint, render_template s4app = Blueprint("s4app", __name__, template_folder="apptemp", url_prefix="/lantu") #前三个参数必须给,后一个可选,如果添加了在访问时/lantu/s4app @s4app.route("/s4app") def s4appa(): # 蓝图实例名不要与函数名重复 return render_template("s4app.html")
#在flask实例上注册蓝图,才能访问 from user_reg import views app.register_blueprint(views.s4app)
5.flask中的特殊装饰器
@app.before_request # 请求进入视图函数之前
@app.after_request # 响应返回客户端之前
如果有多个before_request按从上到下执行,多个after_request按从下到上执行
正常情况下流程:be1 - be2 - be3 - af3 - af2 - af1
异常情况下流程:be1 - af3 - af2 - af1
@app.before_request def be1(): if request.path == "/login": return None if not session.get("user"): return redirect("/login") @app.after_request def af1(response): return response
@app.errorhandler(404) # 重定义错误页面返回信息
@app.errorhandler(404) #填错误码 def error404(error): #接收参数为错误信息 return render_template("my_error.html")