【Flask从入门到精通:第十二课:常用模块、蓝图 Blueprint】

devtools/2024/10/20 6:35:08/

常用模块

Faker

文档: https://faker.readthedocs.io/en/master/locales/zh_CN.html

批量生成测试数据: https://github.com/joke2k/faker

pip install faker -i https://pypi.douban.com/simple

代码:

python">from flask import Flask
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)class Config(object):DEBUG = True# 数据库连接配置# SQLALCHEMY_DATABASE_URI = "数据库类型://数据库账号:密码@数据库地址:端口/数据库名称?charset=utf8mb4"SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/flaskdemo?charset=utf8mb4"# 动态追踪修改设置,如未设置只会提示警告SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO = Falseapp.config.from_object(Config)db = SQLAlchemy(app=app)class Student(db.Model):"""学生信息模型"""__tablename__ = "db_student"id = db.Column(db.Integer, primary_key=True,comment="主键")name = db.Column(db.String(15), comment="姓名")age = db.Column(db.SmallInteger, comment="年龄")sex = db.Column(db.Boolean, default=True, comment="性别")email = db.Column(db.String(128), comment="邮箱地址")money = db.Column(db.Numeric(10,2), default=0.0, comment="钱包")def __repr__(self):return f"{self.name}<Student>"# 自定义批量生成学生
import random,click
from faker import Faker
# 自定义终端命令
@app.cli.command("faker_user")     # 指定终端命令的调用名称
@click.argument("num", default=5, type=int)  # 命令的选项
def faker_user_command(num):"""生成测试学生信息"""faker = Faker(locale="ZH_CN")for i in range(num):sex = bool( random.randint(0,1) )student = Student(name= faker.name_male() if sex else faker.name_female(),age=random.randint(15,60),sex=sex,email=faker.free_email(),money= float( random.randint(100,100000) / 100 ),)db.session.add(student)# 在循环外面统一提交db.session.commit()@app.route("/")
def index():return "ok"if __name__ == '__main__':with app.app_context():db.create_all()app.run()"""
export FLASK_APP=manage.py
flask faker-user 10
"""

flasksession_87">flask-session

flask-session,允许设置session到指定的存储空间中,例如:redis/mongoDB/mysql。

文档: https://flask-session.readthedocs.io/en/latest/

pip install Flask-Session

使用session之前,必须配置一下配置项:

python"># session秘钥
app.config["SECRET_KEY"] = "*(%#4sxcz(^(#$#8423"

SQLAlchemy存储session的基本配置

需要手动创建session表,在项目第一次启动的时候,使用db.create_all()来完成创建。

python">from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# 引入session存储驱动类
from flask_session import Session
# 引入sessio操作类,注意:引入路径不同,大小写不同的。
from flask import sessionapp = Flask(__name__, template_folder="templates", static_folder="static")db = SQLAlchemy()# 实例化session存储类
session_store = Session()# 配置
app.config.update({"DEBUG": True,# 使用session之前,必须配置一下秘钥"SECRET_KEY": "*(%#4sxcz(^(#$#8423",# 要把存储到SQLAlchemy,必须配置数据库连接# "SQLALCHEMY_DATABASE_URI": "数据库类型://数据库账号:密码@数据库地址:端口/数据库名称?charset=utf8mb4""SQLALCHEMY_DATABASE_URI": "mysql://root:123@127.0.0.1:3306/flaskdemo?charset=utf8mb4",# 动态追踪修改设置,如未设置只会提示警告"SQLALCHEMY_TRACK_MODIFICATIONS": False,# 查询时会显示原始SQL语句"SQLALCHEMY_ECHO": False,# 把session通过SQLAlchmey保存到mysql中"SESSION_TYPE": "sqlalchemy",  # session类型为sqlalchemy"SESSION_SQLALCHEMY": db,  # SQLAlchemy的数据库连接对象"SESSION_SQLALCHEMY_TABLE": 'db_session',  # session要保存的表名称"SESSION_PERMANENT": True,    # 如果设置为True,则关闭浏览器session就失效"SESSION_USE_SIGNER": True,  # 是否对发送到浏览器上session的cookie值进行添加签名,防止串改。"SESSION_KEY_PREFIX": "session:"  # session数据表中sessionID的前缀,默认就是 session:
})db.init_app(app)# 务必保证在数据库配置初始化以后才进行session存储类的初始化
session_store.init_app(app)# 如果要把session保存到数据库中,则必须先执行db.create_all() 让数据库提前创建session表。否则使用session时报错。
@app.route("/create")
def create_table():db.create_all()  # 为项目中被识别的所有模型创建数据表return "ok"@app.route("/drop")
def drop_table():db.drop_all()  # 为项目中被识别的所有模型删除数据表return "ok"@app.route("/")
def index():return "ok"@app.route("/set")
def set_session():session["uname"] = "xiaoming"session["age"] = 18return "ok"@app.route("/get")
def get_session():print(session.get("uname"))print(session.get("age"))return "ok"@app.route("/del")
def del_session():# 此处的删除,不是删除用户对应的session表记录,而是删除session值而已。print(session.pop("uname"))print(session.pop("age"))return "ok"if __name__ == '__main__':app.run()

redis保存session的基本配置

这个功能必须确保,服务器必须已经安装了redis而且当前项目虚拟环境中已经安装了redis扩展库

pip install flask-redis -i https://pypi.douban.com/simple

flask-redis是第三方开发者为了方便我们在flask框架中集成redis数据库操作所封装一个redis操作库、

flask中要基于flask-redis进行数据库则可以完成以下3个步骤即可:

from flask import Flask
from flask_redis import FlaskRedis# 实例化
app = Flask(__name__)
session_redis = FlaskRedis(config_prefix="SESSION")
user_redis = FlaskRedis(config_prefix="USER")
order_redis = FlaskRedis(config_prefix="ORDER")# 初始化 flask_redis
session_redis.init_app(app)
user_redis.init_app(app)
order_redis.init_app(app)@app.route("/")
def q2():user_redis.setnx("doing", 100)return "ok"if __name__ == '__main__':app.run(host="0.0.0.0", port=5000, debug=True)

在redis中保存session,代码:

python">from flask import Flask
from flask_redis import FlaskRedis
from flask_session import Session
from flask import sessionapp = Flask(__name__, template_folder="templates", static_folder="static")redis0 = FlaskRedis(config_prefix="REDIS")
redis1 = FlaskRedis(config_prefix="SESSION_REDIS")
session_store = Session()
# 配置
app.config.update({"DEBUG": True,# 使用session之前,必须配置一下秘钥"SECRET_KEY": "*(%#4sxcz(^(#$#8423","REDIS_URL": "redis://:123456@127.0.0.1:6379/0","SESSION_REDIS_URL": "redis://:123456@127.0.0.1:6379/1",# 把session保存到redis中"SESSION_TYPE": "redis",  # session类型为sqlalchemy"SESSION_PERMANENT": True,  # 如果设置为True,则关闭浏览器session就失效"SESSION_USE_SIGNER": True,  # 是否对发送到浏览器上session的cookie值进行添加签名,防止串改。"SESSION_KEY_PREFIX": "session:",  # session数据表中sessionID的前缀,默认就是 session:# session保存数据到redis时启用的链接对象"SESSION_REDIS": redis1,      # 用于连接redis的配置
})redis0.init_app(app)
redis1.init_app(app)# 务必保证session存储类初始化之前,redis已经完成初始化了。
session_store.init_app(app)@app.route("/")
def index():return "ok"@app.route("/set")
def set_session():session["uname"] = "xiaoming"session["age"] = 18return "ok"@app.route("/get")
def get_session():print(session.get("uname"))print(session.get("age"))return "ok"@app.route("/del")
def del_session():# 此处的删除,是直接删除保存在redis中的数据,当所有session被删除,则key也会消失了。print(session.pop("uname"))print(session.pop("age"))return "ok"if __name__ == '__main__':app.run()

蓝图 Blueprint

模块化

随着flask程序越来越复杂,我们需要对程序进行模块化的处理,之前学习过django的子应用管理,flask程序进行可以进行类似的模块化处理保存代码。

简单来说,Blueprint 是一个存储视图方法/模型代码的容器(目录),这些操作在这个Blueprint 被注册到flask的APP实例对象应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理客户端请求的视图。

Flask使用Blueprint让应用实现模块化,在Flask中Blueprint具有如下属性:

  • 一个项目可以具有多个Blueprint
  • 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名,也就是说每一个蓝图都可以像django那样有属于自己的路由前缀
  • 在一个flask项目中,同一个BluePrint模块可以注册多次,也就是说一个蓝图可以对应多个不同的url地址。
  • Blueprint目录可以保存单独属于自己的模板目录保存自己的模板文件、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
  • 在一个flask项目初始化时,就应该要注册需要使用的Blueprint,否则项目不识别Blueprint蓝图

注意:flask中的Blueprint并不是一个完整的项目应用,它不能独立运行,而必须要把蓝图blueprint注册到某一个flask项目中才能使用。

flask中,要使用蓝图Blueprint可以分为四个步骤:

  1. 手动创建一个蓝图的包目录,例如users,并在__init__.py文件中创建蓝图实例对象users_blueprint
python">from flask import Blueprint# 等同于 app = Flask(__name__),只是这里并非一个独立的flask项目,所以需要在第一个参数中,指定蓝图名称,其他参数与之前实例化app应用对象是一样的。
users_blueprint = Blueprint("users", __name__)
# users_blueprint = Blueprint('users',__name__,static_folder="users_static")
  1. 在这个users蓝图目录下创建蓝图的子文件, 其中我们可以创建views.py文件,保存当前蓝图使用的视图函数
python"># 光写视图,不用写路由
def login():return "用户登录视图"def register():return "用户注册视图"
  1. users/__init__.py中引入views.py中所有的视图函数并绑定路由
python">from flask import Blueprint
from . import views# 等同于 app = Flask(__name__),只是这里并非一个独立的flask项目,所以需要在第一个参数中,指定蓝图名称,其他参数与之前实例化app应用对象是一样的。
users_blueprint = Blueprint("users", __name__)
# users_blueprint = Blueprint('users',__name__,static_folder="users_static")# 给蓝图注册视图与绑定视图的路由,路由必须以/斜杠开头
users_blueprint.add_url_rule("/login", view_func=views.login)
users_blueprint.add_url_rule("/reg", view_func=views.register)# 子路由
print(users_blueprint.deferred_functions)
  1. 在主应用下程序入口manage.py文件中把这个users_blueprint蓝图对象注册app实例对象中,运行起来。
python">from flask import Flask
from users import users_blueprintapp = Flask(__name__, template_folder="templates", static_folder="static")# 配置
app.config.update({"DEBUG": True,
})@app.route("/")
def index():return "我是ok"app.register_blueprint(users_blueprint, url_prefix='/users')if __name__ == '__main__':# 总路由print(app.url_map)app.run()

当这个应用启动后,通过/users/可以访问到蓝图中定义的视图函数

蓝图运行机制

  • 蓝图Blueprint实际上的作用就是,充当当前蓝图目录下的所有视图和url路由地址的绑定关系的临时容器
  • 在视图函数被蓝图的add_url_rule方法注册时,这个操作本质就是将视图和url地址的映射关系添加到蓝图的子路由列表deferred_functions中。
  • 蓝图对象根本没有路由表,当我们在蓝图中的视图函数上调用route装饰器(或者add_url_role函数)注册路由时,它只是在蓝图对象的内部的deferred_functions(子路由列表)中添加了一个路由项(路由项实际上就是一个绑定了视图和url地址的lambda匿名函数)
  • 当执行app.register_blueprint()注册蓝图时,app应用实例对象会将从蓝图对象的 deferred_functions列表中循环取出每一个之前注册的路由项,并把app应用实例对象自己作为参数执行路由项对应的lambda匿名函数,lambda匿名函数执行以后就会调用app.add_url_rule() 方法,这就将蓝图下子路由列表之前暂存的路由全部添加到了app应用实例对象的url_map总路由表中了,所以用户就可以在flask中访问到了蓝图中的视图。当然,能访问蓝图下的视图,自然也就可以通过视图调用其他的功能,例如:蓝图下的其他功能函数或其他的模型对象了。

蓝图的url拼接

当我们在app应用实例对象上注册一个蓝图时,可以指定一个url_prefix关键字参数(这个参数默认是/)

在这里插入图片描述

在app应用实例对象的最终的路由表 url_map中,在蓝图上注册的路由URL自动被加上了这个路由前缀,这个可以保证在多个蓝图中使用相同的子路由而不会最终引起冲突,只要在注册蓝图时将不同的蓝图挂接到不同的自路径即可。

注意:有了蓝图以后,在flask使用url_for在使用时,如果要生成一个蓝图里面的视图对应的路由地址,则需要声明当前蓝图名称+视图名称

python"># url_for('蓝图名称.视图函数名')
url_for('users.login') # /users + /login   /users就是蓝图中的路由前缀  /login就是子路由

users/views.py,代码:

python">from flask import url_fordef login():return "用户登录视图"def register():print(url_for("users.login"))return "用户注册视图"

访问:

在这里插入图片描述

注册蓝图下的静态文件[很少使用]

和app应用对象不同,蓝图对象创建时不会默认注册静态目录的路由。需要我们在创建时手动指定 static_folder 参数。

下面的代码将蓝图所在目录下的static_users目录设置为静态目录

users/__init__.py,代码:

python">from flask import Blueprint
from . import views# 等同于 app = Flask(__name__),只是这里并非一个独立的flask项目,所以需要在第一个参数中,指定蓝图名称,其他参数与之前实例化app应用对象是一样的。
users_blueprint = Blueprint("users", __name__, static_folder="static")
# users_blueprint = Blueprint('users',__name__,static_folder="users_static")# 给蓝图注册视图与绑定视图的路由,路由必须以/斜杠开头
users_blueprint.add_url_rule("/login", view_func=views.login)
users_blueprint.add_url_rule("/reg", view_func=views.register)# 子路由
print(users_blueprint.deferred_functions)

在这里插入图片描述

现在就可以使用http://127.0.0.1:5000/users/static/images/avatar.jpg 访问users/static/目录下的静态文件了.

当然,也可以修改访问静态文件的路径 :可以在创建蓝图对象时使用 static_url_path 来改变静态目录的url地址。

python">from flask import Blueprint
from . import views# 等同于 app = Flask(__name__),只是这里并非一个独立的flask项目,所以需要在第一个参数中,指定蓝图名称,其他参数与之前实例化app应用对象是一样的。
users_blueprint = Blueprint("users", __name__, static_folder="static", static_url_path="/assets")
# users_blueprint = Blueprint('users',__name__,static_folder="users_static")# 给蓝图注册视图与绑定视图的路由,路由必须以/斜杠开头
users_blueprint.add_url_rule("/login", view_func=views.login)
users_blueprint.add_url_rule("/reg", view_func=views.register)# 子路由
print(users_blueprint.deferred_functions)

现在就可以使用http://127.0.0.1:5000/users/static/assets/avatar.jpg访问users/static/目录下的静态文件了.

在这里插入图片描述

设置蓝图下的html模版[很少使用]

创建蓝图中的模板目录templates,users/__init__.py,代码:

python">from flask import Blueprint
from . import views# 等同于 app = Flask(__name__),只是这里并非一个独立的flask项目,所以需要在第一个参数中,指定蓝图名称,其他参数与之前实例化app应用对象是一样的。
users_blueprint = Blueprint("users", __name__, static_folder="static", static_url_path="/assets", template_folder="templates")
# users_blueprint = Blueprint('users',__name__,static_folder="users_static")# 给蓝图注册视图与绑定视图的路由,路由必须以/斜杠开头
users_blueprint.add_url_rule("/login", view_func=views.login)
users_blueprint.add_url_rule("/reg", view_func=views.register)# 子路由
print(users_blueprint.deferred_functions)

视图users/views.py,代码:

python">from flask import url_for
from flask import render_templatedef login():title = "用户登录视图"return render_template("login.html", **locals())def register():print(url_for("users.login"))return "用户注册视图"

模板代码,users/templates/index.html,代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>{{ title }}</h1>
</body>
</html>

在这里插入图片描述

注意:如果公司使用了flask1.x版本,则不能出现项目根目录下和蓝图目录下2个templates目录的情况,否则项目根目录下的templates模板会覆盖蓝图目录下的同名模板,flask会优先加载项目根目录下的模板。


http://www.ppmy.cn/devtools/59365.html

相关文章

面试题 29. 顺时针打印矩阵

顺时针打印矩阵 题目描述示例 题解 题目描述 输入一个矩阵&#xff0c;按照从外向里以顺时针的顺序依次打印出每一个数字。 示例 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 题解 从外往里一圈一圈遍历并…

昇思25天学习打卡营第六天|应用实践/计算机视觉/Vision Transformer图像分类

心得 运行模型似乎有点靠天意&#xff1f;每次跑模型之前先来个焚香沐浴&#xff1f;总之今天是机器视觉的最后一课了&#xff0c;尽管课程里强调模型跑得慢&#xff0c;可是我的这次运行&#xff0c;居然很快的就看到结果了。 如果一直看我这个系列文章的小伙伴&#xff0c;…

微服务治理新篇章:Eureka中细粒度策略管理实现

微服务治理新篇章&#xff1a;Eureka中细粒度策略管理实现 在微服务架构中&#xff0c;服务的治理和管理是确保系统稳定性和可扩展性的关键。Eureka作为Netflix开源的服务发现框架&#xff0c;提供了基本的服务注册与发现功能。然而&#xff0c;随着微服务规模的扩大和业务需求…

[Spring] Spring Web MVC案例实战

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

clion中建立c文件工程,读取或创建sqlite3数据库文件

1.首先前往SQLite官网下载sqlite3所需文件 SQLite Download Page 2.解压文件&#xff0c;将其中的sqlite3.c和sqlite3.h拷贝到你对应的文件工程中 3.修改CMakeLists.txt文件&#xff0c;添加编译选项及连接文件 4.运行代码及查询数据库文件

codeforce 954 div3 G2题

思路&#xff1a; 质因子分解可以顺着分解&#xff0c;也可以逆着分解 即找到每一个数字的倍数&#xff0c;再找到每一个数字的因数 const int N 5e510; vector<int> ff[N]; vector<int> f[N]; vector<int> g[N];void solve(){int n;cin>>n;vector&l…

AI发展中的伦理挑战与应对策略

AI发展中的伦理挑战与应对策略 人工智能&#xff08;AI&#xff09;的快速发展在为社会带来许多便利和创新的同时&#xff0c;也带来了诸多伦理挑战。这些挑战主要集中在数据隐私侵犯、信息茧房的制造、歧视性算法、深度伪造技术等方面。针对这些问题&#xff0c;需要从多个层…

Pygame开发五子棋之人机对战游戏

引言 Pygame是一个基于Python的开源游戏开发库&#xff0c;它包含了丰富的多媒体功能&#xff0c;尤其是针对游戏开发所需的各种组件。如果你对游戏开发感兴趣&#xff0c;但又不想从底层开始编写所有东西&#xff0c;Pygame可以成为一个理想的起点。本文将介绍Pygame的基本概…