目录

1.flask-migrate

2.flask-session

3.蓝图:Blueprint

4.蓝图的运行机制

1.数据库迁移:flask-migrate

1.Flask的数据库迁移

  • 在开发过程中,需要修改数据库模型,而且还要在修改之后更新数据库。最直接的方式就是删除旧表,但这样会丢失数据。

  • 更好的解决办法是使用数据库迁移框架,它可以追踪数据库模式的变化,然后把变动应用到数据库中。

  • 在Flask中可以使用Flask-Migrate扩展,来实现数据迁移。并且集成到Flask-Script中,所有操作通过命令就能完成。

  • 为了导出数据库迁移命令,Flask-Migrate提供了一个MigrateCommand类,可以附加到flask-script的manager对象上。

2.flask-migrate的安装

  1. pip install flask-migrate

3.在flask代码中引入数据库迁移

  1. from flask import Flask
  2. from config import Config
  3. from flask_sqlalchemy import SQLAlchemy
  4. from flask_migrate import Migrate,MigrateCommand # 1.引入Migrate和MigrateCommand
  5. from flask_script import Manager,Command
  6.  
  7. app = Flask(__name__,template_folder='templates')
  8. app.config.from_object(Config)
  9.  
  10. manage = Manager(app)
  11.  
  12. db = SQLAlchemy(app)
  13.  
  14. # 2.创建migrate对象。第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
  15. migrate = Migrate(app,db)
  16.  
  17. # 3.manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
  18. manage.add_command('db',MigrateCommand)
  19.  
  20. achieve = db.Table('tb_achievement',
  21. db.Column('student_id', db.Integer, db.ForeignKey('tb_student.id')),
  22. db.Column('course_id', db.Integer, db.ForeignKey('tb_course.id'))
  23. )
  24.  
  25. class Course(db.Model):
  26. __tablename__ = 'tb_course'
  27. id = db.Column(db.Integer, primary_key=True)
  28. name = db.Column(db.String(64), unique=True)
  29. price = db.Column(db.Numeric(6,2))
  30. teacher_id = db.Column(db.Integer, db.ForeignKey('tb_teacher.id'))
  31. students = db.relationship('Student', secondary=achieve, backref='courses', lazy='subquery')
  32.  
  33. def __repr__(self):
  34. return 'Course:%s'% self.name
  35.  
  36. class Student(db.Model):
  37. __tablename__ = 'tb_student'
  38. id = db.Column(db.Integer, primary_key=True)
  39. name = db.Column(db.String(64), unique=True)
  40. email = db.Column(db.String(64),unique=True)
  41. age = db.Column(db.SmallInteger,nullable=False)
  42. sex = db.Column(db.Boolean,default=1)
  43.  
  44. def __repr__(self):
  45. return 'Student:%s' % self.name
  46.  
  47. class Teacher(db.Model):
  48. __tablename__ = 'tb_teacher'
  49. id = db.Column(db.Integer, primary_key=True)
  50. name = db.Column(db.String(64), unique=True)
  51. courses = db.relationship('Course', backref='teacher', lazy='subquery')
  52.  
  53. def __repr__(self):
  54. return 'Teacher:%s' % self.name
  55.  
  56. @app.route("/")
  57. def index():
  58. return "ok"
  59.  
  60. if __name__ == '__main__':
  61. manage.run()

4.flask中数据库迁移常用的命令

1.创建迁移版本仓库

  1. # 这个命令会创建migrations文件夹,所有迁移文件都放在里面。
  2. python main.py db init

2.创建迁移版本仓库

  1. # 这里等同于django里面的 makemigrations,生成迁移版本文件
  2. python main.py db migrate -m 'initial migration'

3.升级迁移版本库的版本

  1. python main.py db upgrade

4.降级迁移版本库的版本

  1. python main.py db downgrade

5.回滚到指定版本

  1. python manage.py db downgrade 版本号 # 返回到指定版本号对应的版本

6.查看数据库迁移历史(可查看数据库迁移版本号)

  1. python manage.py db history
  2.  
  3. # 输出格式:<base> -> 版本号 (head), initial migration

一般数据迁移的步骤是:init-->migrate-->upgrade/downgrade

2.flask-session

flask-session:允许设置session到指定存储的空间中

安装命令: https://pythonhosted.org/Flask-Session/

1.flask-session的安装和配置

  1. pip install flask-Session

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

  1. SECRET_KEY = "*(%#4sxcz(^(#$#8423" # session秘钥

2.redis保存session的基本配置

  1. from flask import Flask,session
  2. from flask_redis import FlaskRedis
  3. from flask_session import Session
  4. app = Flask(__name__)
  5. redis = FlaskRedis()
  6. session_store = Session()
  7. class Config():
  8. # DEBUG调试模式
  9. DEBUG = True
  10.  
  11. # json多字节转unicode编码
  12. JSON_AS_ASCII = False
  13.  
  14. # 数据库链接配置
  15. SECRET_KEY = "*(%#4sxcz(^(#$#8423"
  16.  
  17. # 1.session存储方式为redis
  18. SESSION_TYPE = "redis"
  19.  
  20. # 2.session保存数据到redis时启用的链接对象
  21. SESSION_REDIS = redis
  22.  
  23. # 3.如果设置session的生命周期是否是会话期, 为True,则关闭浏览器session就失效
  24. SESSION_PERMANENT = True
  25.  
  26. # 4.是否对发送到浏览器上session的cookie值进行加密
  27. SESSION_USE_SIGNER = True
  28.  
  29. # 5.保存到redis的session数的名称前缀
  30. SESSION_KEY_PREFIX = "session:"
  31.  
  32. # 6.redis的链接配置
  33. REDIS_URL = "redis://localhost:6379/1"
  34.  
  35. app.config.from_object(Config) # 将Config类注册到app上
  36. redis.init_app(app) # 将flask-redis对象挂载到app上
  37. session_store.init_app(app) # 将flask-session对象挂载到app上
  38.  
  39. @app.route("/")
  40. def index():
  41. session["username"] = "xiaoming"
  42. return "Ok"
  43.  
  44. @app.route("/get_session")
  45. def get_session():
  46. print( session["username"] )
  47. return "ok"
  48.  
  49. @app.route("/redis1")
  50. def set_redis():
  51. # redis给集合数据类型/哈希数据类型设置值
  52. redis.set("username","xiaohuihui")
  53. redis.hset("brother","zhangfei","17")
  54. return "ok"
  55.  
  56. @app.route("/redis2")
  57. def get_redis():
  58. user = redis.get("username").decode()
  59.  
  60. brother = redis.hgetall("brother")
  61. print(brother["zhangfei".encode()].decode())
  62.  
  63. return "ok"
  64.  
  65. if __name__ == '__main__':
  66. app.run()

执行程序,访问127.0.0.1:5000,即可将session值存储到redis中

如图所示:

3.SQLAlchemy存储session的基本配置

  1. from flask import Flask,session
  2. from flask_redis import FlaskRedis
  3. from flask_session import Session
  4. from flask_sqlalchemy import SQLAlchemy
  5.  
  6. app = Flask(__name__)
  7. db = SQLAlchemy()
  8. redis = FlaskRedis()
  9. session_store = Session()
  10.  
  11. class Config():
  12.  
  13. ......
  14. '''数据库链接配置'''
  15. # SQLALCHEMY_DATABASE_URI = "mysql://账号:密码@IP/数据库名?编码"
  16. SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/students?charset=utf8mb4"
  17.  
  18. # 动态追踪修改设置,如未设置只会提示警告
  19. SQLALCHEMY_TRACK_MODIFICATIONS = True
  20.  
  21. # 查询时会显示原始SQL语句
  22. SQLALCHEMY_ECHO = True
  23.  
  24. '''数据库保存session'''
  25. SESSION_TYPE = 'sqlalchemy' # session类型为sqlalchemy
  26. SESSION_SQLALCHEMY = db # SQLAlchemy对象
  27. SESSION_SQLALCHEMY_TABLE = 'tb_session' # session要保存的表名称
  28. SESSION_PERMANENT = True # 如果设置为True,则关闭浏览器session就失效。
  29. SESSION_USE_SIGNER = False # 是否对发送到浏览器上session的cookie值进行加密
  30. SESSION_KEY_PREFIX = 'session:' # 保存到session中的值的前缀
  31.  
  32. db.init_app(app)
  33. app.config.from_object(Config)
  34. redis.init_app(app)
  35. session_store.init_app(app)
  36.  
  37. @app.route("/")
  38. def index():
  39. session["username"] = "xiaohui"
  40. return "Ok"
  41.  
  42. @app.route("/get_session")
  43. def get_session():
  44. return session["username"]
  45.  
  46. if __name__ == '__main__':
  47. # with app.app_context():
  48. # db.create_all()
  49. app.run()

执行程序,访问127.0.0.1:5000,即可将session值存储到mysql中

如图所示:

3.蓝图:Blueprint

1.蓝图:模块化

随着flask程序越来越复杂,我们需要对程序进行模块化的处理,之前学习过python的模块化管理,于是针对一个简单的flask程序进行模块化处理

简单来说,Blueprint 是一个存储视图方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。

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

  • 一个项目可以具有多个Blueprint

  • 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名

  • 在一个应用中,一个模块可以注册多次

  • Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的

  • 在一个应用初始化时,就应该要注册需要使用的Blueprint

但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

Blueprint对象用起来和一个应用/Flask对象差不多,最大的区别在于一个 蓝图对象没有办法独立运行,必须将它注册到一个应用对象上才能生效.

2.简单使用蓝图

1.创建一个蓝图的包,例如users,并在__init__.py文件中创建蓝图对象

  1. from flask import Blueprint
  2. # 1. 创建蓝图目录并对蓝图对象进行初始化
  3. users_blue = Blueprint("users",__name__,template_folder="users_templates",static_folder='users_static',static_url_path="/libs")

2.在这个蓝图目录下, 创建views.py文件,保存当前蓝图使用的视图函数

  1. from . import users_blue
  2. from flask import render_template
  3. # 2. 编写视图
  4. @users_blue.route("/")
  5. def index():
  6. return render_template("index.html",title="users/index/index.html")
  7.  
  8. @users_blue.route("/list")
  9. def list():
  10. return "users/list"

3.在users/__init__.py中引入views.py中所有的视图函数

  1. # 3. 注册视图
  2. from .views import *

4.在主应用main.py文件中的app对象上注册这个users蓝图对象

  1. # 4. 注册蓝图
  2. from users import users_blue
  3. app.register_blueprint(users_blue,url_prefix="/users")

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

3.蓝图的url前缀

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

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

  • url_for在使用时,如果要生成一个蓝图里面的视图对应的路由地址,则需要声明当前蓝图名称+视图名称

  1. url_for('users.home') # /users/home

4.注册蓝图的静态文件的相关路由

1.static_folder:设置静态文件目录

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

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

  1. from flask import Blueprint
  2. # 通过static_folder参数设置静态文件目录
  3. users_blue = Blueprint("users",__name__,static_folder='users_static')

2.static_url_path:改变静态文件的路由

定制静态目录URL规则 :可以在创建蓝图对象时使用 static_url_path 来改变静态目录的路由。

下面的示例将为 users/static 文件夹的路由设置为 /lib

  1. from flask import Blueprint
  2. # 通过static_url_path设置静态文件路由
  3. users_blue = Blueprint("users",__name__,static_folder='users_static',static_url_path='/lib')

访问http://127.0.0.1:5000/users/libs/1.jpg 即可查看到图片

5.设置蓝图中模板的目录

蓝图对象默认的模板目录为系统的模版目录,可以在创建蓝图对象时使用 template_folder 关键字参数设置模板目录

  1. users_blue = Blueprint("users",__name__,static_folder='users_static',static_url_path='/libs',template_folder='users_templates')

注意:如果在 templates 中存在和 templates_users 有同名模板文件时, 则系统会优先使用 templates 中的文件

4.蓝图的运行机制

1.蓝图运行机制的简要介绍

  • 蓝图是保存了一组将来可以在应用对象上执行的操作,注册路由就是一种操作

  • 当在app对象上调用 route 装饰器注册路由时,这个操作将修改对象的url_map路由表

  • 然而,蓝图对象根本没有路由表,当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项

  • 当执行app对象的 register_blueprint() 方法时,应用对象将从蓝图对象的 defered_functions 列表中取出每一项,并以自身作为参数执行该匿名函数,即调用应用对象的 add_url_rule() 方法,这将真正的修改应用对象的usr_map路由表

2.蓝图运行机制的详细介绍

day96:flask:flask-migrate&flask-session&蓝图Blueprint&蓝图的运行机制的更多相关文章

  1. 第九篇 Flask 中的蓝图(BluePrint)

    第九篇 Flask 中的蓝图(BluePrint)   蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? ...

  2. Flask路由与蓝图Blueprint

    需求分析: 当一个庞大的系统中有很多小模块,在分配路由的时候怎么处理呢?全部都堆到一个py程序中,调用@app.route? 显然这是很不明智的,因为当有几十个模块需要写路由的时候,这样程序员写着写着 ...

  3. Flask 中的蓝图(BluePrint)

    蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开 怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查 ...

  4. 用 Flask 来写个轻博客 (16) — MV(C)_Flask Blueprint 蓝图

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 Blueprint 蓝图 定义一个蓝图 注册一个蓝图 创建蓝 ...

  5. python 全栈开发,Day120(路由系统, 实例化Flask的参数, 蓝图(BluePrint), before_request after_request)

    昨日内容回顾 1.Flask: from flask import Flask app = Flask(__name__) # 从源码中可以看出,Flask集成的run方法是由werkzeug中的ru ...

  6. Flask蓝图Blueprint和特殊装饰器

    Flask 中的 蓝图 Blueprint 不能被run的flask实例:相当于django中的app01 应用 蓝图作用:功能隔离 路由隔离 Blueprint就是 一个不能run的flask 蓝图 ...

  7. Flask 蓝图(Blueprint)

    蓝图使用起来就像应用当中的子应用一样,可以有自己的模板,静态目录,有自己的视图函数和URL规则,蓝图之间互相不影响.但是它们又属于应用中,可以共享应用的配置.对于大型应用来说,我们可以通过添加蓝图来扩 ...

  8. flask Blueprint蓝图

    首先要了解蓝图的作用,模拟场景在团队开发过程中团队每个人都在写自己负责的功能模块,那多个py文件模板,我们如果完成后需要运行是不是要运行多个服务?但是我们的项目是一个整体,而不是零散的,所以我们怎么把 ...

  9. Flask最强攻略 - 跟DragonFire学Flask - 第九篇 Flask 中的蓝图(BluePrint)

    蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看 ...

随机推荐

  1. linux中root目录下下指定磁盘空间扩容

    1 查看当前磁盘情况 fdisk -l /dev/sda1 2048 6143 2048 83 Linux /dev/sda2 * 6144 1054719 524288 83 Linux /dev/ ...

  2. C# 中的只读结构体(readonly struct)

    翻译自 John Demetriou 2018年4月8日 的文章 <C# 7.2 – Let's Talk About Readonly Structs>[1] 在本文中,我们来聊一聊从 ...

  3. liunx命令的运用

    工作中用到了一些命令,记忆才深刻 1.查看服务器内存:free -h 2.查看服务器磁盘空间:df -h 3.切root用户:sudo su root 输入密码 4.查看liunx服务器下的所有用户: ...

  4. OpenCascade拓扑对象之:Face的方向、参数域和曲面间的关系

    @font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...

  5. python时间Time模块

    时间和日期模块 关注公众号"轻松学编程"了解更多. python程序能用很多方式处理日期和时间,转换日期格式是一种常见的功能. python提供了一个time和calendar模块 ...

  6. windows下redis的PHP扩展安装

    1.查看已安装PHP的信息,打印phpinfo(); 主要看三个信息:PHP版本,是否线程安全(TS或NTS),系统是x64还是x86.用以确定扩展文件的版本. 2.需要php_redis.dll这个 ...

  7. 写文档太麻烦,试试这款 IDEA 插件吧!

    前言 每次开发完新项目或者新接口功能等,第一件事就是提供接口文档.说到接口文档,当然是用 Markdown 了.各种复制粘贴字段,必填非必填,字段备注,请求返回示例等等.简直是浪费时间哇.所以想到了开 ...

  8. 关于Java中泛型、反射和注解的扫盲篇

    泛型 泛型概念   泛型是在JDK1.5之后引入的,旨在让我们写出更加通用化,更加灵活的代码.通用化的手段在于让数据类型变得参数化,定义泛型时,对应的数据类型是不确定的,泛型方法被调用时,会指定具体类 ...

  9. python00

    # Python* [什么是 Python 生成器?](#什么是-Python-生成器)* [什么是 Python 迭代器?](#什么是-Python-迭代器)* [list 和 tuple 有什么区 ...

  10. 自己常用的Content-Type几种值用法

    Content-Type 的值类型: application/json:消息主体是序列化后的 JSON 字符串 这里要注意的是 我在使用webapi,前台使用$.ajax的时候 假如我要传递的数据为 ...