一、Flask-Session

  我们使用过flask内置的session,知道它是把session存放在浏览器,即客户端。今天要学习的flask-session是flask的第三方组件,看一下它和flask内置的session有什么不同以及它的使用方法。

  flask-session是flask框架的session组件,flask内置session使用签名cookie保存,而该组件则将支持session保存到多个地方,如:

    - redis

    - memcached

    - filesystem

    - mongodb

    - sqlalchmey

1、安装flask-session

pip3 install flask-session

2、回顾flask自带的session的使用方法

  from flask import Flask, session

  app = Flask(__name__)
  app.secret_key = 'afhaslhg' # 一定要有这句   @app.route('/')
  def index():
  session['user'] = 'value'
  return 'hello'   if __name__ == '__main__':
   app.run(debug=True)

  启动程序,使用浏览器访问http://127.0.0.1:5000时,会看到如下session:

3、flask-session的使用(以保存到redis中为例)

  from flask import Flask, session
  from flask_session import Session # 导入flask-session中的Session类
  from redis import Redis   app = Flask(__name__)
  # 对实例进行配置
  app.config["SESSION_TYPE"] = "redis"
  app.config["SESSION_REDIS"] = Redis(host="127.0.0.1",port=6379,db=6)
  
  Session(app) # 把原来app中的 session 进行替换   @app.route('/')
  def index():
   session['user'] = 'value'
   return 'hello'   if __name__ == '__main__':
   app.run(debug=True)

  启动程序(redis服务端要),浏览器访问http://127.0.0.1:5000时,浏览器session如下图:

  打开redis客户端,进行如下操作:

二、WTForms组件

  WTForms是flask的组件,类似于django的modelform组件。

1、安装

pip3 install wtforms

2、使用(以登陆和注册为例)

  wtf.py文件:

from flask import Flask, render_template, request
from wtforms.fields import simple, core
from wtforms import validators
from wtforms import Form app = Flask(__name__) # 定义注册类
class RegForm(Form):
username = simple.StringField(
label="用户名",
validators=[
validators.DataRequired(message='该字段不能为空'),
validators.Length(min=3, max=10, message='用户名必须3-10个字符')
],
id="user_id",
render_kw={"class": "user_name"}
)
password = simple.PasswordField(
label="密码",
validators=[
validators.DataRequired(message='该字段不能为空'),
validators.Length(min=6, max=12, message='用户名必须6-12个字符')
],
id="pwd",
render_kw={"class": "pwd"}
)
repassword = simple.PasswordField(
label="确认密码",
validators=[
validators.EqualTo(fieldname='password', message='两次密码不一致')
],
id="re_pwd",
render_kw={"class": "re_pwd"}
)
email = simple.StringField(
label="邮箱",
validators=[
validators.DataRequired(message='该字段不能为空'),
validators.Email(message='必须符合邮箱格式')
],
id="email",
render_kw={"class": "email"}
)
gender = core.RadioField(
label='性别',
coerce=int, # 提交的数据类型,即1或者2的数据类型
choices=(
(1, '女'), # 元组第一个元素是value,第二个元素是显示的值
(2, '男')
),
default=1 # 默认值为1
)
hobby = core.SelectMultipleField(
label='爱好',
validators=[validators.Length(min=1, max=3, message='爱好可为1-3个')],
coerce=str, # 注意,类型为str时,下面choices中每个元组第一个值必须带引号
choices=(
('', '足球'),
('', '篮球'),
('', '唱歌'),
('', '跳舞')
),
default=(1,3) # 默认选中两个
)
# button = simple.SubmitField() # 渲染提交按钮 # 定义登陆类
class LoginForm(Form):
username = simple.StringField(
label="用户名", # lable标签标记内容
validators=[
validators.DataRequired(message='该字段不能为空'),
validators.Length(min=3, max=10, message='用户名必须3-10个字符')
], # 校验条件,可迭代条件,因为可能校验多个条件
description='this is a description', # 描述标记
id="user_id", # 标签id
widget=None, # 默认组件(比如input type="text") 在StringField中已经被实例化了
render_kw={"class":"my_login"} # 添加属性和值
)
password = simple.PasswordField(
label="密码",
validators=[
validators.DataRequired(message='该字段不能为空'),
validators.Length(min=6, max=12, message='用户名必须6-12个字符')
],
description='this is a description',
id="pwd",
default=None,
render_kw={"class": "pwd"}
) @app.route("/reg", methods=["GET", "POST"])
def reg():
if request.method == "GET":
rf = RegForm()
return render_template('reg.html', wtf=rf)
else:
rf = RegForm(request.form)
if rf.validate():
return rf.data.get('username')
else:
print(rf.data)
print(rf.errors)
return render_template('reg.html', wtf=rf) @app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
lf = LoginForm() # 实例化登录类
return render_template('index.html', wtf=lf)
else:
lf = LoginForm(request.form) # 将用户提交数据传入登陆类
if lf.validate(): # 校验用户提交的数据
return lf.data.get('username') # 正确的在lf.data中
else: # 错误的在lf.errors中
return render_template('index.html', wtf=lf) app.run(debug=True)

  reg.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="" method="post" novalidate>
{% for field in wtf %}
<p>
{{ field.label }}
{{ field }}
{{ field.errors.0 }}
</p>
{% endfor %}
<input type="submit" value="注册">
</form>
</body>
</html>

  login.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="" method="post" novalidate>
<p>
{{ wtf.username.label }}
{{ wtf.username }}{{ wtf.username.errors.0 }}
</p>
<p>
{{ wtf.password.label }}
{{ wtf.password }}{{ wtf.password.errors.0 }}
</p>
<input type="submit" value="登录">
</form>
</body>
</html>

三、数据库连接池(POOL)

1、回顾pymysql(python操作数据库的模块)的使用

  参考博客:https://www.cnblogs.com/li-li/p/9810867.html

2、DBUtils - python数据库连接池

  1)安装DBUtils

pip3 install DBUtils

  2)创建并使用连接池

    dbpool.py文件:

import pymysql
from DBUtils.PooledDB import PooledDB POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5, # 链接池中最多闲置的链接,0和None不限制
maxshared=3, # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。
# 如:0 = None = never,
# 1 = default = whenever it is requested,
# 2 = when a cursor is created,
# 4 = when a query is executed,
# 7 = always
host="127.0.0.1",
port=3306,
user="root",
password="",
charset="utf8",
db="s15"
)

    sqlhelper.py文件:

from dbpool import POOL
import pymysql def create_conn():
conn = POOL.connection()
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) return conn,cursor def close_conn(conn,cursor):
cursor.close()
conn.close() def insert(sql,args):
conn,cursor = create_conn()
res = cursor.execute(sql,args)
conn.commit()
close_conn(conn,cursor)
return res def fetch_one(sql,args):
conn,cursor = create_conn()
cursor.execute(sql,args)
res = cursor.fetchone()
close_conn(conn,cursor)
return res def fetch_all(sql,args):
conn,cursor = create_conn()
cursor.execute(sql,args)
res = cursor.fetchall()
close_conn(conn,cursor)
return res sql = "insert into users(name,age) VALUES (%s, %s)"
insert(sql,("mjj",9)) sql = "select * from users where name=%s and age=%s"
print(fetch_one(sql,("mjj",9)))

 

Flask(5)- Flask-Session组件、WTForms组件、数据库连接池(POOL)的更多相关文章

  1. Flask(4):wtforms组件 & 数据库连接池 DBUtils

    wtforms 组件的作用: --- 生成 HTML 标签 --- form 表单验证 示例代码: app.py from flask import Flask, render_template, r ...

  2. Flask&&人工智能AI --5 Flask-session、WTForms、数据库连接池、Websocket

    未完待续.... DButils 什么是数据库连接池 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库 ...

  3. flask数据库连接池DBUtils

    数据库连接池 为啥要使用数据库连接池 频繁的连接和断开数据库,消耗大,效率低 DBUtils可以创建多个线程连接数据库,且一直保持连接,不会断开 执行数据库操作时,由数据池分配线程,当数据池空时,可选 ...

  4. 基于DBUtils实现数据库连接池及flask项目部署

    阅读目录 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 数据库连接池原理 模式一: 模式二: 数据库连接池 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 ...

  5. [数据库连接池] Java数据库连接池--DBCP浅析.

    前言对于数据库连接池, 想必大家都已经不再陌生, 这里仅仅设计Java中的两个常用数据库连接池: DBCP和C3P0(后续会更新). 一. 为何要使用数据库连接池假设网站一天有很大的访问量,数据库服务 ...

  6. java数据库连接池技术简单使用

    JDBCDemo.java: package com.itheima.jdbc; import java.sql.Connection; import java.sql.PreparedStateme ...

  7. Java数据库连接池--DBCP浅析.

    一. 为何要使用数据库连接池假设网站一天有很大的访问量,数据库服务器就需要为每次连接创建一次数据库连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.数据库连接是一种关键的有限的昂贵 ...

  8. Flask Session ,pymysql ,wtforms组件 虚拟virtualenv venv

    https://www.cnblogs.com/wupeiqi/articles/5713330.html session def create_app(): print() app=Flask(__ ...

  9. flask wtforms组件详解

    一.简介 在flask内部并没有提供全面的表单验证,所以当我们不借助第三方插件来处理时候代码会显得混乱,而官方推荐的一个表单验证插件就是wtforms.wtfroms是一个支持多种web框架的form ...

随机推荐

  1. CCNA2.0笔记_NAT

    NAT:园区网内的PC是私有地址,整个园区网共享一个公有IP,如果园区网内的PC不做NAT,那么在发数据包给外网的时候会出现传输问题 NAT的原理:改变IP包头,使目的地址.源地址或两个地址在包头中被 ...

  2. 替换jar中的指定文件

     替换jar 包下面的class 文件,很多人会想到直接用winrar 打开替换,在一般的情况下, 是可行的,但是如果说这个jar 的代码经过混淆后,会有大小写不同,文件名是相同的,在windos ...

  3. sql命令大全

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...

  4. phpcms 初次建站心得

    最近要给客户建个网站,考虑到效率问题,直接找了个开源的phpcms,(现在被收购了,以前的时候我还知道是个开源的).由于对这个东西不熟悉,原来就是了解一些,php的建站系统,php的MVC框架.故此, ...

  5. 目的:将两个三T的硬盘做成LVM(sdc,sdd)

    parted创建硬盘分区并创建LVM 2013年12月26日 13:37:15 阅读数:4835 目的:将两个三T的硬盘做成LVM(sdc,sdd) 一.parted将硬盘进行分区:1)parted的 ...

  6. Java and unsigned int, unsigned short, unsigned byte, unsigned long, etc. (Or rather, the lack thereof)

    http://darksleep.com/player/JavaAndUnsignedTypes.html —————————————————————————————————————————————— ...

  7. 在使用add()方法添加组件到容器时,必须指定将其放置在哪个区域中

    BorderLayout是Window.Frame和Dialog的默认布局管理器,其将容器分成North.South.East.West和Center 5个区域,每个区域只能放置一个组件. 在使用ad ...

  8. 酷狗缓存文件kgtemp的加密方式

    [转自:http://www.cnblogs.com/KMBlog/p/6877752.html] 首先对比了一下缓存文件和下载好的mp3文件,发现缓存文件多了1024个字节,而且对比了几个缓存文件, ...

  9. point-position目标定位

    双站探测同一目标会构成两条直线:(飞行目标定位2 - ostartech - 博客园 https://www.cnblogs.com/wxl845235800/p/8858116.html) 测角偏差 ...

  10. Ad Hoc Distributed Queries组件

    http://www.cnblogs.com/870060760JR/p/6016080.html SQL Server 阻止了对组件“Ad Hoc Distributed Queries”的 STA ...