Flask 轻便的web框架-2
内容叙述
-
endpoint
- endpoint相当于django里面的别名,可以用于反向解析url
- Mapping 路由地址和endpoint - 路由地址和视图函数Mapping endpoint在同一个app中不能出现重复,默认值是视图函数名(一个装饰器装饰多个函数,endpoint命名不能一样否则报错,路由也不能一样,否则第二个匹配不到)
from flask import Flask,redirect app = Flask(__name__) def warp(func): def inner(*args,**kwargs): return redirect("/home") return inner @app.route("/temp1",endpoint="temp1") @warp def temp1(): return "I am temp1" @app.route("/temp2",endpoint="temp2") @warp def temp2(): return "I am temp2" @app.route("/home") def home(): return "I am home" if __name__ == '__main__': app.run(debug=True) #解析:多个装饰器装饰函数,从下往上执行,一个装饰器装饰多个函数,会报错,错误类型如下 AssertionError: View function mapping is overwriting an existing endpoint function: inner #视图函数正在覆盖现有的端点函数,如果加了endpoint等同于inner.__name__ = func.__name__ 其函数名字,但只是改了一下名字是不行的,Flask内部方法进行此类操作通过endpoint,具体详见源码解析
-
url_for
- 反向获取url地址,默认为视图函数名
from flask import url_for @app.route("/info",methods=["GET","POST"],endpoint="r_info") def student_info(): print(url_for("r_info"))#/info return "hello"
1.路由配置:
-
Flask中的路由
@app.route(配置路由)
-
rule
- 用于路由地址
@app.route("/login") def login(): ... @app.route("/home") def home(): ...
-
methods
- 允许进入视图函数的请求方式
@app.route("/home",methods=["GET","POST"]) def home(): ...
-
defaults
- 默认路由参数
from flask import Flask,redirect app = Flask(__name__) @app.route("/h",defaults={"count":20}) # 传入参数,否则报错 def home(count): return f"200 OK {count}" if __name__ == '__main__': app.run()
-
strict_slashes
- 是否严格遵循路由匹配规则,url地址结尾符“/”的控制False,路径“/”是否存在均可以访问,True:结尾必须不能是"/", 为True给加'/'
#访问地址:/info @app.route("/info",strict_slashes=True) def student_info(): return "hello old boy info" #访问地址:/infos 或 /infos/ @app.route("/infos",strict_slashes=False) def student_infos(): return "hellos"
-
redirect_to
- 永久重定向 响应码:301,308 永久转移
from flask import Flask,redirect app = Flask(__name__) @app.route("/h",defaults={"count":20}) def home(count): return f"200 OK {count}" @app.route("/res",redirect_to="/h") def res(): return "hello" if __name__ == '__main__': app.run()
-
动态参数路由1
@app.route("/temp/<page>_<id>_<type>",endpoint="temps") def temp(page,id,type): print(page,id,type) return "%s_%s_%s"%(page,id,type) if __name__ == '__main__': app.run() #浏览器输入http://127.0.0.1:5000/temp/23_32_43 #返回:23 32 43
-
动态参数路由2
@app.route("/get_img/<filename>") def get_img(filename): file_path = os.path.join("img",filename) return send_file(file_path) if __name__ == '__main__': app.run(debug=True)
from flask import url_for
def hmoea():
print(url_for('homea'))
rule "/login" 路由地址
methods 允许进入视图函数的请求方式
endpoint Mapping路由地址和endpoint - 路由地址和视图函数Mapping endpoint 在同一个app中不能出现重复,默认值是视图函数
@app def app endpoint=app ❌❌❌
defaults 默认路由参数
stric_slashes 是否严格遵循路由匹配规则
redirect_to 永久重定向 308
动态参数路由: "/get_muisc/<filename>" def get_music(filename)可以分页,获取文件,解决分页,解决正则路由问题
2.Flask初始化配置
- 配置位置:app = Flask(
__name__
)
template_folder 模板文件存放目录
static_folder 静态文件存放目录 默认值 是 static 默认值static
static_url_path 静态文件访问路径 默认值 是 / + static_folder
当修改template_folder="img" ----> 自动修改成static_url_path='/img'。除非重新自动修改成static_url_path="static"
- 示例1:
import os
from flask import Flask,render_template,send_file
app = Flask(__name__,template_folder="./templates",static_folder="static",static_url_path="/static")
@app.route("/")
def index():
return render_template("index.html")
#前端index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="/static/2.jpg" alt="">
</body>
</html>
#静态文件存放目录是static, 静态文件访问路径static_url_path="/static"
#前端通过/static/2.jpg,找到静态文件存放目录,并提取里面文件
static_url_path 用于放静态文件路径
static_folder 用于存放静态文件目录
- 示例2:
import os
from flask import Flask,render_template,send_file
app = Flask(__name__,template_folder="templates",static_folder="img",static_url_path="/static")
@app.route("/")
def index():
return render_template("index.html")
@app.route("/img/<filename>")
def get_img(filename):
filepath = os.path.join("img",filename)#用static_folder.
return send_file(filepath)
if __name__ == '__main__':
app.run(debug=True)
#前端index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="/static/1.jpg" alt="">#用static_url_path
</body>
</html>
- 示例3:
@app.route("/img/<filename>")
def get_img(filename):
print(filename)
filepath = os.path.join("img",filename)#通过static_folder拼接图片地址。并返回send_file
return send_file(filepath)
3.Flask实例配置
- app.config(类似于django的setting配置)
-
参数介绍:
ENV 当前运行虚拟环境 debug 编辑模式 testing 测试,日志打印 propaagate_exceptions secret_key 密钥 permanent_session_lifetime session默认时间 配置的时候写的是秒 server_name 配置服务所处于的域名(Nginx自己匹配) session_cookie_name 存储在浏览器session名字 session_cookie_Path JSONIFY_MIMETYPE 设置jsonify 的content-type
-
创建settings.py文件
import hashlib,time
class DebugConfig(object):
"""调试模式"""
DEBUG = True
SECRET_KEY = "#$#sdrer"
PERMANENT_SESSION_LIFETIME = 3600
SESSION_COOKIE_NAME = "hello"
class TestConfig(object):
"""线上测试"""
TESTING = True
SECRET_KEY = hashlib.md5(f"{time.time()}asdg3#¥#@#{time.time()}".encode("utf8")).hexdigest()
PERMANENT_SESSION_LIFETIME = 3600
SESSION_COOKIE_NAME = "BBADASD@#@#@$##!$@"
- 导入模块,为app配置setting
from setting import DebugConfig
app = Flask(__name__)
app.config.from_object(DebugConfig)#匹配配置
4.Flask中的蓝图
- Flask 中的蓝图 Blueprint(app01)
不能被run的Flask 实例 不存在config
1.创建2个蓝图
"""
class Blueprint
def __init__(
self,
name,
import_name,
static_folder=None,
static_url_path=None,
template_folder=None,
url_prefix=None,
subdomain=None,
url_defaults=None,
root_path=None,
cli_group=_sentinel,
):
"""
#blue_pic1.py
from flask import Blueprint
bp = Blueprint("app01",__name__)
@bp.route("/add_user")
def add_user():
return "添加用户"
@bp.route("/find_user")
def find_user():
return "查看用户"
@bp.route("/drop_user")
def drop_user():
return "删除用户"
@bp.route("/up_user")
def up_user():
return "修改用户"
#blue_pic2.py
from flask import Blueprint
car_bp = Blueprint("app02",__name__,url_prefix="/car")
#url_prefix 可指定url前缀
@car_bp.route("/add_user")
def add_user():
return "car添加用户"
@car_bp.route("/find_user")
def find_user():
return "car查看用户"
@car_bp.route("/drop_user")
def drop_user():
return "car删除用户"
@car_bp.route("/up_user")
def up_user():
return "car修改用户"
- 函数导入
from flask import Flask
from setting import DebugConfig
from blue_pic1 import bp
from blue_pic2 import car_bp
app = Flask(__name__,template_folder="template")
app.config.from_object(DebugConfig)
app.register_blueprint(bp)#注册蓝图
app.register_blueprint(car_bp)#注册蓝图
if __name__ == '__main__':
app.run()
- 浏览器输入:url找到对应网址
- 小练习:url_for在蓝图应用
from flask import Blueprint, url_for, redirect
bp = Blueprint("app01",__name__)
@bp.route("/bps",endpoint="bps")
def bps():
return redirect(url_for("app01.dd"))
#通过url_for("蓝图标识.endpoint值")可以获得其他视图函数的rule(url路径),通过redirect(url_for("app01.dd")),可以重定向网页
@bp.route("/bpdd",endpoint="dd")
def bpdd():
return "this is bpdd..."
5.特殊装饰器(类似中间件)
-
@app.before_request() 在请求进入视图函数之前,做出处理
-
@app.after_request() 在响应返回客户端之前结束视图函数之后
-
be + af 请求生命周期:
- 正常:be1->be2->vf->af2->af1
- 异常:be1->af2->af1
- 只要有响应的返回,af全部响应
-
@app.errorhandler(404) 错误处理
-
特殊装饰器实例:类似于django中间件
from flask import Flask, send_file,session
from setting import DebugConfig
from blue_pic1 import bp
from blue_pic2 import car_bp
app = Flask(__name__,template_folder="template")
app.config.from_object(DebugConfig)
app.register_blueprint(bp)
app.register_blueprint(car_bp)
@app.before_request
def be1():
print("I am Be1")
@app.before_request
def be2():
print("I am Be2")
@app.after_request
def af1(res):
print("I am af1")
return res
@app.after_request
def af1(res):
print("I am af2")
return res
@app.errorhandler(404)
"""监听错误,出现404错误,直接跳转baidu页面"""
def error404(error_message):
print(error_message)
return send_file("https://www.baidu.com/")
@app.route("/set_session")
def set_session():
print("舞曲")
session["key"] = "1234556775465"
return "session创建"
@app.route("/get_session")
def get_session():
print(session.get("key"))
return "session获取"
if __name__ == '__main__':
app.run()
#I am Be1
#I am Be2
#1234556775465
#I am af2
#I am af1
be + af 请求生命周期:
- 正常:be1->be2->vf->af2->af1
- be1异常:be1->af2->af1
6.源码解析:
6.1解析route装饰器源码
-
pic1:
-
pic2:
6.2解析route中methods方法
-
pic1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库