扩展
蓝图内置扩展 (实现的是路由的拆分)
1 '''----------- app.py -------------''' 2 from flask import Flask 3 from users_views import blue1 4 from orders_views import blue2 5 6 app = Flask(__name__) 7 8 # 路由注册 9 app.register_blueprint(blueprint=blue1) 10 app.register_blueprint(blueprint=blue2) 11 12 13 if __name__ == '__main__': 14 app.run()
1 ''' ------------ users_views.py ---------------''' 2 from flask import Blueprint 3 # blue1 的设置(名字,导入的名字,前缀名称) 4 blue1 = Blueprint("blue1",__name__, url_prefix="/users") 5 6 # 用blue1设置路由,用前缀名字区分相同名字的路由:http://127.0.0.1:5000/users/ 7 @blue1.route("/") 8 def index(): 9 return "用户的 Blue 信息" 10 11 12 @blue1.route("/user/") 13 def home(): 14 return "用户信息"
1 ''' ----------- orders_vieews.py ----------''' 2 from flask import Blueprint 3 # blue2 的设置(名字,导入的名字,前缀名称) 4 blue2 = Blueprint("blue2", __name__, url_prefix="/orders") 5 6 # 用blue2设置路由,用前缀名字区分相同名字的路由:http://127.0.0.1:5000/orders/ 7 @blue2.route("/") 8 def haha(): 9 return "订单的 blue2 信息" 10 11 12 @blue2.route("/orders/") 13 def ppp(): 14 return "订单信息"
静态文件路径
1 from flask import Flask 2 from users_views import blue1 3 from orders_views import blue2 4 # 静态文件路径配置。static_folder='news/static' 是配置新的静态文件的路径 5 app = Flask(__name__,static_folder='news/static') 6 7 # 路由注册 8 app.register_blueprint(blueprint=blue1) 9 app.register_blueprint(blueprint=blue2)
终端命令启动项目插件扩展:
- 实现:flask-script
- 安装:pip install flask-script
- 作用:实现命令键入的方式 启动项目
- 使用:在终端键入:python app.py runserver
- 查看帮助文档: python app.py runserver --help
- 设置指定端口: python app.py runserver -h ip地址 -p 端口号
- 设置自动重启: python app.py runserver -r
- 设置调试模式: python app.py runserver -d
- shell脚本调试: python app.py shell 在终端内添加model数据
- 配置:
1 from flask import Flask 2 from flask_script import Manager 3 4 app = Flask(__name__) 5 # 配置flask-script 6 manager = Manager(app=app) 7 8 @app.route('/') 9 def hello_world(): 10 return 'Hello World!' 11 12 # 使用flask-script 13 if __name__ == '__main__': 14 manager.run() 15 16 flask-script
对象模型迁移数据库表扩展:
- 实现:flask-migrate
- 安装:pip install flask-migrate -i http://pypi.douban.com/simple
- 作用:迁移,可以自动将模型转变成数据库中的表
- 配置:
- 在extension.py扩展文件中绑定app和db。详见下面代码块 ;创建一个Migrate对象,传递app和db进去
- 然后,在manage.py启动文件的manager对象上添加指令:manager.add_command("db",MigrateCommand)
- 使用:
- 首次使用需要初始化: python manage.py db init
- 如果模型有变更,生成迁移文件:python manage.py db migrate
- 将迁移文件映射到数据库中: python manage.py db upgrade
- 后悔返回,回滚操作: python manage.py db downgrade
- extension.py
1 from flask_migrate import Migrate 2 from flask_sqlalchemy import SQLAlchemy 3 4 db = SQLAlchemy() 5 # 扩展文件添加配置信息。创建一个Migrate对象。 6 migate = Migrate() 7 8 9 # 应用一个函数,使用函数传参数将app导入初始化 10 def init_ext(app): 11 db.init_app(app) 12 migate.init_app(app,db) # 将app和db以参数的形式传递进去。注册上
- manage.py
1 # 注册迁移工具命令行 2 manager.add_command("db",MigrateCommand) 3 4 if __name__ == '__main__': 5 manager.run()
- 未拆分写法
1 from flask_migrate import Migrate, MigrateCommand 2 from flask_script import Manager 3 from app import create_app, db 4 5 app = create_app() 6 manager = Manager(app=app) 7 8 # 创建迁移工具实例 9 migrate = Migrate() 10 migrate.init_app(app=app,db=db) 11 12 13 # 注册迁移工具命令行 14 manager.add_command("db",MigrateCommand) 15 16 if __name__ == '__main__': 17 manager.run()
数据库模型和对象关系扩展:
- 实现:SQLAlchemy; pymysql驱动
- 安装:pip install flask-sqlalchemy ;pip install pymysql
- 作用:
- 配置:
1 from flask import Flask, render_template 2 from flask_sqlalchemy import SQLAlchemy 3 4 app = Flask(__name__) 5 6 # 配置连接sqlite数据库的指定信息。SQLite数据库连接不需要额外驱动,也不需要用户名和密码 7 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hello.sqlite' 8 # 设False为更好的兼容性,禁止对象追踪修改 9 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 11 db = SQLAlchemy(app) 12 13 14 # 配置连接mysql数据库的指定信息。dialect+driver://username:password@host:port/database 15 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:guoyapeng@localhost:3306/FlaskModel' 16 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
17 db = SQLAlchemy(app) 18 19 20 if __name__ == '__main__': 21 app.run()
- 使用:下面链接文件中的 模型板块
https://www.cnblogs.com/TMMM/p/11450872.html
缓存技术cache扩展库插件:
- 实现:flask_caching
- 安装:pip install flask-caching
- 作用:
- 减少磁盘IO可以大幅度提升服务器性能。
- 可以将经常访问的数据缓存起来,再次使⽤用时直接从缓存中获取,而不是每次都操作数据库。
- 字段:
from flask_caching import Cache cache = Cache() cache.init_app(app=app, config={'CACHE_TYPE': 'simple'})
1 CACHE_REDIS_URL # 连接到Redis服务器的URL。一键配置示例 2 cache = Cache(config={ 3 "CACHE_TYPE": "redis", 4 "CACHE_REDIS_URL":"redis://:localhost@127.0.0.1:6379/1",}) 5 6 # 以下参数是所有的类型共有的 7 CACHE_NO_NULL_WARNING = "warning" # null类型时的警告消息 8 CACHE_ARGS = [] # 在缓存类实例化过程中解包和传递的可选列表,用来配置相关后端的额外的参数 9 CACHE_OPTIONS = {} # 可选字典,在缓存类实例化期间传递,也是用来配置相关后端的额外的键值对参数 10 CACHE_DEFAULT_TIMEOUT # 默认过期/超时时间,单位为秒 11 CACHE_THRESHOLD # 缓存的最大条目数 12 13 CACHE_TYPE: # 设置缓存的类型 14 CACHE_TYPE = null # 默认的缓存类型,无缓存 15 CACHE_TYPE = 'simple' # 使用本地python字典进行存储,非线程安全 16 CACHE_TYPE = 'filesystem' # 使用文件系统来存储缓存的值 17 CACHE_TYPE = 'memcached' # 使用memcached服务器缓存 18 CACHE_TYPE = 'redis' # 使用redis作为缓存
1 CACHE_TYPE = 'filesystem' # 使用文件系统来存储缓存的值 2 CACHE_DIR = "" # 文件目录 3 4 CACHE_TYPE = 'memcached' # 使用memcached服务器缓存 5 CACHE_KEY_PREFIX # 设置cache_key的前缀 6 CAHCE_MEMCACHED_SERVERS # 服务器地址的列表或元组 7 CACHE_MEMCACHED_USERNAME # 用户名 8 CACHE_MEMCACHED_PASSWORD # 密码 9 10 CACHE_TYPE = 'redis' # 使用redis作为缓存 11 CACHE_KEY_PREFIX # 设置cache_key的前缀 12 CACHE_REDIS_HOST # redis地址 13 CACHE_REDIS_PORT # redis端口 14 CACHE_REDIS_PASSWORD # redis密码 15 CACHE_REDIS_DB # 使用哪个数据库
- 配置
- manage.py
from flask_script import Manager from app import create_app app = create_app() manager = Manager(app=app) if __name__ == '__main__': manager.run()
- app/__init__.py
from flask import Flask from app import views, ext def create_app(): app = Flask(__name__)
# 注册缓存配置 ext.init_cache(app) # 注册路由 app.register_blueprint(views.bp) return app
- app/ext.py
1 from flask_caching import Cache 2 3 cache = Cache() 4 5 def init_cache(app): 6 7 # CACHE_TYPE = 'redis' 使用redis作为缓存 8 # CACHE_KEY_PREFIX 设置cache_key的前缀。不设置表示默认 9 # CACHE_REDIS_HOST redis地址 10 # CACHE_REDIS_PORT redis端口 11 # CACHE_REDIS_PASSWORD redis密码。没密码就不用设置 12 # CACHE_REDIS_DB 使用哪个数据库,不设置表示随机 13 14 app.config["CACHE_TYPE"] = "redis" 15 app.config["CACHE_REDIS_HOST"] = "127.0.0.1" 16 app.config["CACHE_REDIS_PORT"] = 6379 17 # 设置缓存到app上 18 cache.init_app(app=app)
- 使用
- movies/views.py
1 from time import sleep 2 from app.ext import cache 3 4 @user_blue.route("/learn/") 5 @cache.cached(60) # 设置缓存,60秒有效 6 def learn(): 7 print("开始学习") 8 sleep(10) 9 print("结束学习") 10 return "缓存技术,提高学习时间"
会话技术session扩展库插件:
- 实现:flask_session
- 作用:实现http的长链接,
- 安装:pip install flask-session
- 配置:
1 import datetime 2 from flask import Flask 3 from flask_session import Session 4 from app import views 5 6 def create_app(): 7 8 app = Flask(__name__) 9 10 # 为sesson设置一个密钥key值。两种方式,推荐第二种 11 # app.secret_key = 'asdfghjkl' 12 app.config['SECRET_KEY'] = 'd53a40dae292df9d409ef64e4a04905d' 13 14 # flssk-session 扩展配置 15 # 指定 flask-session 扩展将 session 数据持久化到 redis 中 16 app.config['SESSION_TYPE'] = 'redis' 17 18 # 指定 flask-session 存储在 redis 中的 session id的前缀 19 app.config['SESSION_KEY_PREFIX'] = 'flask:session' 20 21 # 自定义 session 过期时间 22 app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=7) 23 24 # 创建 flask-session 的 Session 对象 25 sess = Session() 26 27 # 将 flask-session 扩展初始化,跟app建立链接 28 sess.init_app(app=app) 29 30 app.register_blueprint(views.bp) # 注册路由 31 return app
- 使用: 以下链接中的 session会话 模块
https://www.cnblogs.com/TMMM/p/11478808.html
管理⽤户登录登出扩展库插件:
- 实现:flask-login
- 安装:pip install flask-login
- 作用:是一个专门用来管理用户登录退出的扩展库
- 步骤:
- 1. 在extension.py中 app上注册flask-login扩展,指定登陆页面。如下两行代码
- 2. 在model.py中 在登陆对象(User)中继承 UserMixin类,提供便捷的功能
- 3. 在views.py中 增加load_user回调函数,导入扩展文件包加装饰器@login_manager.user_loader。
- 供flask-login扩展在内部加载当前登陆的用户对象。flask-login默认通过user id的方式,调用load_user函数,获得用户对象
- 4. 登陆成功后,调用login_user(user)将登陆成功的对象绑定到session中
- 5. 使用lagin_required装饰器,保护访问受限的视图函数
- 配置:
- manage.py 注册
1 # 添加扩展 3 from flask import Flask 4 from flask.ext.login import LoginManager 6 app = Flask(__name__) 8 # 1.实例化login_manager 9 login_manager = LoginManager()
10 # 2.将login_manager与app绑定 11 login_manager.init_app(app)
12 # 3.设置登录视图名称。如果未登录用户请求只有登录用户才能访问的视图,则重定向到这个设置的登录视图。 13 login_manager.login_view = 'blue.login'
14 # 4.如果未设置登录视图,则直接返回401错误。设置登录错误信息 15 login_manager.login_message = '请登录!'
-
- models.py 继承
1 from flask_login import UserMixin 2 from flask_sqlalchemy import SQLAlchemy 3 4 db = SQLAlchemy() 5 # 让User继承自UserMixin。 6 class User(UserMixin,db.Model): 7 __tablename__= "users" 8 id = db.Column(db.Integer,primary_key=True) 9 username = db.Column(db.String(16),unique=True,nullable=False) 10 password = db.Column(db.String(256),unique=True,nullable=False)
-
- views.py 初始化
1 # 告诉ext.py中login_manager的用户是从哪来的。用户加载的地方 2 @login_manager.user_loader 3 def load_user(user_id): 4 return User.query.get(user_id)
- 使用
1 """ 2 状态切换: 3 login_user # 登录 4 logout_user # 退出登录 5 6 路由保护: 7 login_required # 保护需要登录才能访问的路路由 8 9 当前用户: 10 current_user # 哪⾥都可以使⽤(在模板中不需要分配) 11 12 实现回调: 13 @login_manager.user_loader 14 def load_user(uid): 15 return User.query.get(uid) 16 """
1 #属性 is_authenticated 2 #当用户登录成功后,该属性为True。 3 4 #属性 is_active 5 #如果该用户账号已被激活,且该用户已登录成功,则此属性为True。 6 7 #属性 is_anonymous 8 #是否为匿名用户(未登录用户)。 9 10 #方法 get_id() 11 #每个用户都必须有一个唯一的标识符作为ID,该方法可以返回当前用户的ID,这里ID必须是Unicode。
7 <body> 8 9 {# 当前用户:current_user,属性:is_authenticated 当前用户登录成功后该属性为True。 #} 10 {# 判断用户是否登陆,如果登陆显示:用户名、注销、用户主页、关于网站。如果没有登陆显示:请登录、用户主页、关于网站 #}
11 {% if current_user.is_authenticated %} 12 当前登陆用户为:{{ current_user.username }}<a href="{{ url_for("blue.logout") }}">注销</a> 13 {% else %} 14 <a href="{{ url_for("blue.login") }}">请登录</a> 15 {% endif %} 16 <a href="{{ url_for("blue.home") }}">用户主页</a> 17 <a href="{{ url_for("blue.about") }}">关于网站</a> 18 19 </body>
-
- models.py
1 from flask_login import UserMixin 2 from flask_sqlalchemy import SQLAlchemy 3 4 db = SQLAlchemy() 5 6 class User(UserMixin,db.Model): 7 __tablename__= "users" 8 id = db.Column(db.Integer,primary_key=True) 9 username = db.Column(db.String(16),unique=True,nullable=False) 10 password = db.Column(db.String(256),unique=True,nullable=False)
-
- views.py
1 from flask import Blueprint, render_template, request, redirect, url_for, flash 2 from flask_login import login_user, logout_user, login_required 3 from werkzeug.security import generate_password_hash, check_password_hash 4 from app.ext import login_manager 5 from app.models import User, db 6 7 bp = Blueprint('blue', __name__) 8 9 10 @bp.route('/register/', methods=['GET', 'POST']) 11 def register(): 12 if request.method == 'POST': 13 # 处理注册逻辑。 1、检查两次输入的密码是否相等; 2、检查用户名是否重复 14 username = request.form.get('username') 15 password = request.form.get('password') 16 re_password = request.form.get('re_password') 17 18 # 检查两次输入的密码是否相等 19 if password != re_password: 20 return render_template('register.html', msg='两次输入密码不一致', username=username) 21 # 查询数据库中是否有重复的用户名。 .count() 获得查询语句匹配到的行数 22 if User.query.filter_by(username=username).count() > 0: 23 return render_template('register.html', msg='用户名重复', username=username) 24 25 # 对 password 进行加密。进行存储准备 26 password_hash = generate_password_hash(password) 27 user = User() 28 user.username = username 29 user.password = password_hash 30 # 对新注册的用户进行存储 31 db.session.add(user) 32 db.session.commit() 33 34 # flash 闪现消息,可以跨请求传递消息,不跨请求时也可以使用 35 # 本质上:内部会把消息保存到 session中,在下一个请求中通过session获取 36 """ 37 在 html 中使用 38 {% for message in get_flashed_messages() %} 39 {{ message }} 40 {% endfor %} 41 """ 42 flash('注册成功,请登录') 43 return redirect(url_for('blue.login')) 44 return render_template('register.html') 45 46 @bp.route("/login/",methods=["POST","GET"]) 47 def login(): 48 if request.method == "POST": 49 # 处理登陆业务 50 username = request.form.get("username") 51 password = request.form.get("password") 52 53 user = User.query.filter_by(username=username).first() 54 if user is None: 55 return render_template("login.html",msg="用户或密码错误",username=username) 56 if check_password_hash(user.password,password): 57 58 # 登陆成功以后需要将登陆状态保存到session中session['uid']=user.id,使用flask-login的login_user()来完成 59 login_user(user) 60 61 # 即使是post请求,也可以用args获取跳转链接next的参数值,http://127.0.0.1:5000/login/?next=%2Fhome%2F 62 next_url = request.args.get("next") 63 # 如果存在 next 跳转参数,则跳转到 next 页面;否则调转到首页 64 return redirect(next_url or url_for("blue.index")) 65 else: 66 return render_template("login.html", msg="用户或密码错误", username=username) 67 return render_template("login.html") 68 69 # 保护页面。需要配置默认调转页面 70 # 使用装饰器:@login_required 实现:只有登陆的用户,点击home时页面才会看到信息;没有登陆的用户点击会被跳转到登陆页面 71 @bp.route("/home/") 72 @login_required 73 def home(): 74 return "home" 75 76 # 登出操作。用 flask-login的logout_user()自动完成登出时session的清理工作 77 @bp.route("/logout/") 78 def logout(): 79 logout_user() 80 return redirect(url_for("blue.index")) 81 82 # 告诉ext.py中login_manager的用户是从哪来的。用户加载的地方 83 @login_manager.user_loader 84 def load_user(user_id): 85 return User.query.get(user_id) 86 87 88 @bp.route("/about/") 89 def about(): 90 return "about" 91 92 @bp.route('/') 93 def index(): 94 return render_template('index.html')