蓝图内置扩展 (实现的是路由的拆分)
html
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)
终端命令启动项目插件扩展:python
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
对象模型迁移数据库表扩展:mysql
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以参数的形式传递进去。注册上
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()
数据库模型和对象关系扩展:web
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.htmlredis
缓存技术cache扩展库插件:
sql
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 # 使用哪一个数据库
from flask_script import Manager from app import create_app app = create_app() manager = Manager(app=app) if __name__ == '__main__': manager.run()
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
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)
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扩展库插件:shell
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
https://www.cnblogs.com/TMMM/p/11478808.html数据库
管理⽤户登陆登出扩展库插件:json
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 = '请登陆!'
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)
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>
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)
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 # 处理注册逻辑。 一、检查两次输入的密码是否相等; 二、检查用户名是否重复 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')
表单验证模块扩展库插件:
form.py中的 username = StringField(...)匹配 .html中的 <input name="username">
SelectField:下拉框内容在 form 表单类初始化时即肯定。运行中修改不生效(验证时会出错)
QuerySelectField:下拉框内容能够动态从数据库中获取,query_factory指定查询接口
1 from flask_wtf import FlaskForm 2 from wtforms import StringField, PasswordField 3 from wtforms.validators import DataRequired, Length, EqualTo 4 5 6 class RegisterForm(FlaskForm): 7 # 定义页面中显示的字段标签。username是StringField类型 8 username = StringField( 9 # label标签 显示:"用户名" 10 label='用户名', 11 # 验证器:列表类型。 12 validators=[ 13 # DataRequired 必填信息 14 DataRequired(message='用户名为必填') 15 ] 16 ) 17 password = PasswordField( 18 label='密码', 19 validators=[ 20 DataRequired(message='密码为必填'), 21 # 长度验证(最小2,最长4) 22 Length(min=2, max=4, message='密码长度为 2 ~ 4'), 23 ] 24 ) 25 password_confirm = PasswordField( 26 label='重复密码', 27 validators=[ 28 # EqualTo验证和谁相等(要比较的变量) 29 EqualTo('password', message='两次输入的密码必须一致'), 30 ] 31 ) 32 33 34 class LoginForm(FlaskForm): 35 username = StringField( 36 label='用户名', 37 # 默认值:空 38 default='', 39 validators=[ 40 DataRequired(message='用户名为必填') 41 ] 42 ) 43 password = PasswordField( 44 label='密码', 45 validators=[ 46 DataRequired(message='密码为必填'), 47 ] 48 )
1 from flask import Blueprint, render_template, request, redirect, url_for 2 from flask_login import login_user 3 from werkzeug.security import generate_password_hash, check_password_hash 4 from app.ext import login_manager 5 from app.form import RegisterForm, LoginForm 6 from app.models import User, db 7 8 bp = Blueprint('blue', __name__) 9 10 11 @bp.route('/form/register/', methods=['GET', 'POST']) 12 def register_form(): 13 form = RegisterForm() 14 # 普通写法: 15 # if request.method == 'POST': 16 # username = request.form.get('username') 17 18 # form写法 19 # validate_on_submit 内部作了三件事 20 # 一、判断 request.method 是否为 POST, PUT, PATCH, DELETE 21 # 至关于 if request.method == 'POST' 22 # 二、将表单中的同名元素自动绑定到form中的同名属性中 23 # 至关于 username = request.form.get('username') 24 # form.username = username 25 # 三、验证表单数据,根据表单字段中定一个的 validators 26 if form.validate_on_submit(): 27 # 前端数据在form验证经过后,从form获取前端传入的数据 28 print(form.data) 29 username = form.username.data 30 password = form.password.data 31 32 password_hash = generate_password_hash(password) 33 34 user = User() 35 user.username = username 36 user.password = password_hash 37 38 db.session.add(user) 39 db.session.commit() 40 return redirect(url_for('blue.login_form')) 41 return render_template('register_form.html', form=form) # 返回form对象数据 42 43 44 @bp.route('/form/login/', methods=['POST', 'GET']) 45 def login_form(): 46 form = LoginForm() 47 48 # validate_on_submit 内部作了三件事 49 # 一、判断 request.method是否为POST, PUT, PATCH, DELETE 50 # 至关于 if request.method=='POST' 51 # 二、将表单中的同名元素自动绑定到form中的同名属性中 52 # 至关于 username = request.form.get('username') 53 # form.username = username 54 # 三、验证表单数据,根据表单字段中定一个的 validators 55 if form.validate_on_submit(): 56 username = form.username.data 57 password = form.password.data 58 59 # 先根据用户名查询数据库中是否有该数据 60 user = User.query.filter_by(username=username).first() 61 62 if user is None: 63 # 若是查询的对象不存在。手工向form.username.errors追加一条错误信息,经过form显示到前端页面 64 form.username.errors.append('用户或密码错误') 65 return render_template('login_form.html', form=form) 66 67 if check_password_hash(user.password, password): 68 # 若是密码验证经过。使用flask-login的login_user()完成保存登录状态的工做 69 # 登陆成功之后,须要将登陆状态保存到session中,好比:session['uid']=user.id 70 login_user(user) 71 72 # 得到跳转链接,若是url中存在next跳转参数,则跳转到next页面,不然跳转到首页 73 # 经过args获取post请求中的URL的next参数信息 74 next_url = request.args.get('next') 75 return redirect(next_url or url_for('blue.index')) 76 else: 77 form.password.errors.append('用户或密码错误') 78 return render_template('login_form.html', form=form) 79 return render_template('login_form.html', form=form) 80 81 82 @bp.route("/form/index/",methods=['POST','GET']) 83 def index(): 84 return render_template("index.html") 85 86 @login_manager.user_loader 87 def load_user(user_id): 88 return User.query.get(user_id)
1 # 修改资源 2 @app.route('/article/<article_id>/change/', methods=['POST', 'GET']) 3 def article_change(article_id): 4 article = Article.query.get(article_id) 5 # 根据 数据库中查询到的数据 建立 Form 对象 6 # ArticleForm 内部会 将 article 对象的同名属性设置到 ArticleForm 的同名属性上 7 # form.title = article.title 8 # form.content = article.content 9 # form.title.data 10 form = ArticleForm(obj=article) 11 if form.validate_on_submit(): 12 # 使用表单对象的 populate_obj 方法,用已验证表单的内容来填充 Article 对象 13 # 将表单中提交过来的内容,再次反向绑定form上去 14 # article.title = form.title.data 15 # article.content = form.content.data 16 form.populate_obj(article) 17 db.session.commit() 18 19 flash('文章保存成功') 20 return redirect(url_for('blue.article_list')) 21 return render_template('article-change.html', form=form)
1 <body> 2 <form action="{{ url_for("blue.index") }}" method="post"> 3 {# <跨域访问></防跨域访问> #} 4 {{ form.csrf_token }} 5 {# 登录验证失败后: <从新显示输入的信息> </返回错误缘由> #} 6 用户名:<input name="username" type="text" value="{{ form.username.data }}">{{ form.username.errors }} 7 密码:<input name="password" type="password" value="">{{ form.password.errors }} 10 <input type="submit" value="submit"> 11 </form> 12 </body>
1 <body> 2 <form action="" method="post"> 3 {# <csrf防跨域访问></csrf防跨域访问> #} 4 {{ form.csrf_token }} 5 {# flask-wtf 写法 #} 6 {{ form.username.label }} {{ form.username() }} {{ form.username.errors }} 7 {{ form.password.label }} {{ form.password }} {{ form.password.errors }} 8 {{ form.password_confirm.label }} {{ form.password_confirm }} {{ form.password_confirm.errors }} 9 <input type="submit" value="submit"> 10 </form> 11 </body>
方法
""" cache.cached:装饰器,装饰无参数函数,使得该函数结果能够缓存 参数: timeout: 超时时间 key_prefix: 设置该函数的标志 unless: 设置是否启用缓存,若是为True,不启用缓存 forced_update: 设置缓存是否实时更新,若是为True,不管是否过时都将更新缓存 query_string: 为True时,缓存键是先将参数排序而后哈希的结果 cache.memoize:装饰器,装饰有参数函数,使得该函数结果能够缓存 参数: make_name:设置函数的标志,若是没有就使用装饰的函数 其余参数同cached cache.delete_memoized:删除缓存 参数: func_name:缓存函数的引用 *args:函数参数 """
# cache.clear() # 清除缓存全部的缓存,这个操做须要慎重 # cache.get(key) # 获取一个键的值,若是值是json格式会自动转化成字典 # cache.set(key,value,timeout) #设置一个键值,value能够是字典,会自动转化json格式的字符串 # cache.add(key, value, timeout=None) #设置一个键值,若是存在就pass,注意和set的区别 # cache.delete(key) #删除键
流程
使用
1 import random 2 import time 3 from flask import Blueprint 4 from app.ext import cache 5 6 bp = Blueprint("blue",__name__) 7 8 # 缓存视图函数 设置缓存。过时时间10秒 9 @bp.route("/cache_views/") 10 @cache.cached(timeout=10) 11 def cache_views(): 12 """ 13 当经过 cache.cached 缓存视图函数时, 14 在超时以前(timeout<10)访问此视图函数,会先去去缓存中查找,返回缓存中的数据。 15 在超时以后(timeout>10)访问此视图函数,会去缓存中查找,查不到再去数据库中查找,后保存在缓存中并返回数据。 16 :return: 例如:网站首页,不常常变化的话,能够将其存到缓存中 17 """ 18 now = time.time() 19 return str(now) 20 21 22 # 缓存普通函数(单独缓存某个函数,提供更好的复用性) 23 # 推荐指定key_prefix,缓存key的前缀。不然key为调⽤的视图函数所在的路由 24 @cache.cached(timeout=30, key_prefix='random_list') 25 def random_list(): # 随机提取十个数字 26 return [random.randint(0, 100) for _ in range(10)] 27 28 @bp.route('/random_view/') 29 def random_view(): 30 list0 = random_list() # 获取缓存中的十个数据 31 list1 = ",".join(map(str,list0)) 32 list2 = list1 + "------>" + str(random.randint(0, 100)) 33 return list2 34 35 36 # 缓存带参函数 37 @cache.memoize(timeout=30,make_name="random_parm") 38 def random_parm(arg1, arg2): 39 return arg1 + arg2 + random.randint(0,10)
40 # 根据参数值 随机获取数值。参数不一样 得到的随机数不一样,且互不影响 41 # http://127.0.0.1:5000/random_args/1/3/ 结果:4----->73 42 # http://127.0.0.1:5000/random_args/1/2/ 结果:6----->48 43 @bp.route("/random_args/<int:arg1>/<int:arg2>/") 44 def random_args(arg1,arg2): 45 return str(random_parm(arg1,arg2)) + "----->" + str(random.randint(0,100))
46 # 清理缓存。cache.delete(函数名,此函数参数,此函数参数) 47 @bp.route("/delete/<int:arg1>/<int:arg2>") 48 def delete(arg1,arg2): 49 cache.delete(random_parm,arg1,arg2) 51 return "ok" 52 53 54 # 缓存对象(键值对)。cache.set('键', '值', 过时时间) 55 @bp.route("/set_cache/") 56 def set_cache(): 57 cache.set('name', '老王', timeout=30) 58 cache.set('persion', {'name': '晓黎', 'age': 18}, timeout=30) 59 cache.set('lst', [1, 2, 3, 4], timeout=30) 60 # 模拟登陆成功后,把用户身份信息保存到 session 61 session_id = '987654321' 62 cache.set(session_id, {'user_id': 123456}, timeout=1800) 63 64 print(cache.get('name')) 65 print(cache.get('persion')) 66 print(cache.get('lst')) 67 # 模拟 根据 session_id 获取用户的身份信息 68 print(cache.get(session_id)) 69 70 return "ok"
出现缘由:HTTP是无状态协议,使用的短链接,请求周期很是短。使用会话技术为了数据能够跨请求使用,让服务器识别客户端
Cookie:Cookie客户端会话技术,数据都存储在浏览器中,默认携带本网站的全部Cookie。缺点:明文传输不安全
Cookie以key-value存储,支持过时,默认关闭浏览器即失效;不能跨浏览器,不能跨域名访问
1 from flask_script import Manager 2 from app import create_app 3 4 app = create_app() 5 manager = Manager(app=app) 6 7 if __name__ == '__main__': 8 manager.run()
1 from flask import Flask 2 from app import views 3 4 def create_app(): 5 app = Flask(__name__) # 实例化 Flask对象 6 app.register_blueprint(views.bp) # 将蓝图注册到app上 7 return app # 返回出去 Flask实例
1 from flask import Blueprint, request, render_template, make_response, redirect, url_for, abort 2 3 # 用蓝图管理路由,规划url。参数("蓝图名字",__name__) 4 # 蓝图必须了管理的视图在一个文件中,否则不能使用 5 bp = Blueprint("blue",__name__) 6 7 @bp.route('/index') 8 def index(): 9 username = request.cookies.get('username','游客') 10 return render_template("index.html",username= username) 11 12 @bp.route('/login/',methods=['GET','POST']) 13 def login(): 14 if request.method == "POST": 15 username = request.form.get('username') 16 # 模拟登录。使用redirect 来获取响应对象。 17 response = redirect(url_for('blue.index')) 18 # 经过response对象设置cookie 19 response.set_cookie('username',username) 20 return response 21 # render_template(模版名称,**context) **context是须要传递到模版中的 变量 22 return render_template('login.html') 23 24 @bp.route('/logout/') 25 def logout(): 26 # 模拟登录,使用redirect 来获取响应对象。 27 response = redirect(url_for('blue.index')) 28 # 删除cookie 29 response.delete_cookie('username') 30 return response
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>index</title> 6 </head> 7 <body> 8 <h2>欢迎:{{ username }}</h2> 9 <form action="{{ url_for('blue.logout')}}" method="get"> 10 <input type="submit" value="登出"> 11 </form> 12 </body> 13 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="{{ url_for('blue.login')}}" method="post"> 9 <input type="text" name="username" value="" placeholder="请输入用户名"> 10 <input type="submit" value="登陆"> 11 </form> 12 </body> 13 </html>
Session:服务端会话技术,数据都存储在服务端
一、当浏览器第一次访问 web 服务器时,web 服务器会为此浏览器生成一个 session,为这个 session 建立一个惟一的 session_id;
二、在服务器返回请求时,会向浏览器设置 cookies,cookies 中是 key-value 存储reseponse.set_cookies('session_id', session_id, expire=)
三、浏览器再次访问此 web 服务器时,会在请求中带上 cookies 信息,即:session_id: dsfksdlfj232wrwdsf
四、当 web 服务器在次接收到浏览器请求时,会从请求的 cookies 中提取 session_id 的值,
而后根据 session_id 的值,查找到与当前浏览器匹配的 session(好比:从数据库查询等)
绘画特性:依赖于Cookie,以key-value存储、相对安全、不能跨网站,不能跨域名、支持过时默认31天 -> 设置:session.permanent = True
from flask_script import Manager from app import create_app app = create_app() manager = Manager(app=app) if __name__ == '__main__': manager.run()
import datetime from flask import Flask from flask_session import Session from app import views def create_app(): app = Flask(__name__) # 为sesson设置一个密钥key值。两种方式,推荐第二种 # app.secret_key = 'asdfghjkl' app.config['SECRET_KEY'] = 'd53a40dae292df9d409ef64e4a04905d' # flssk-session 扩展配置 # 指定 flask-session 扩展将 session 数据持久化到 redis 中 app.config['SESSION_TYPE'] = 'redis' # 指定 flask-session 存储在 redis 中的 session id的前缀 app.config['SESSION_KEY_PREFIX'] = 'flask:session' # 自定义 session 过时时间 app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=7) # 建立 flask-session 的 Session 对象 sess = Session() # 将 flask-session 扩展初始化,跟app创建连接 sess.init_app(app=app) app.register_blueprint(views.bp) # 注册路由 return app
from flask import Blueprint, render_template, redirect, url_for, request, session # Blueprint: 第一个参数为蓝图自定义名称,第二个参数是 Blueprint 对views.py 导入时须要的名称。 bp = Blueprint('blue',__name__) """ 在 flask 项目中使用 session 1. 为 flask 对象(app)设置secrt key 二、在任何视图函数中均可以像使用字典同样操做 session session['username'] = 'jack' 向session中增长一个 键值对 session.get('username') 从session中根据key获取value session.pop('username') 从session中删除指定的key """ @bp.route('/index/') def index(): # session.get 从 session 中根据key获取对用的值。能够像字典同样操做 username = session.get('username','游客') return render_template('index.html',username=username) @bp.route('/login/',methods=["POST","GET"]) def login(): if request.method == 'POST': username = request.form.get('username') session['username'] = username return redirect(url_for('blue.index')) return render_template('login.html') @bp.route('/logout/') def logout(): session.pop('username') return redirect(url_for('blue.index'))
1 # 设置退出, 2 @app.route('/logout/') 3 def logout(): 4 response = Response('退出成功') 5 response.delete_cookie('session') # 删除session中的session参数 6 session.pop['username'] # 删除session中的username参数值 推荐 7 del session['username'] # 删除session中的username参数值 不存在,会报错 8 return response
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="{{ url_for('blue.login')}}" method="post"> 9 <input type="text" name="username" value="" placeholder="请输入用户名"> 10 <input type="submit" value="登陆"> 11 </form> 12 </body> 13 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h2>欢迎:{{ username }}</h2> 9 <form action="{{ url_for('blue.logout')}}" method="get"> 10 <input type="submit" value="登出"> 11 </form> 12 </body> 13 </html>