Python Flask 扩展学习
- 一、传统的表单验证学习 - 1.1 编写前端的表单 - 1.2 编写 Python 的后台逻辑处理 - 1.3 运行效果
- 二、 使用 Flask-WTF 扩展验证表单 - 2.1 定义表单验证类 - 2.2 编写前端界面 - 2.3 Flask 后台处理 - 2.4 验证
- 三、Python 操作数据库 - 3.1 安装 pymysql - 3.2 配置数据库信息 - 3.3 简单的数据库操作
- 四、使用 Flask-SQLAlchemy (ORM)操作数据库 - 4.1 创建实体类(建表) - 4.2 单表操作之 —— 增加数据 - 4.3 单标操作之 —— 查询数据 - 4.4 单表操作之 —— 修改数据 - 4.5 单表操作之 —— 删除数据 - 4.6 小总结 - 五、Flask-SQLAlchemy 中常用字段 - 5.1 字段类型在这里插入图片描述 - 5.2 列选
一、传统的表单验证学习
学习参考:
W3School
Flask 官方文档
设想有这样一个情景,我们需要实现一个简单的登录功能,用户需要输入账号,密码,以及确认密码,服务器后台验证账号密码是否合理,合理的话,就登录成功,提示登录成功!不成功的话,就通过消息闪现告诉用户哪里出错了
1.1 编写前端的表单
代码语言:javascript复制<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<form method="post">
<label>用户名:label><input type="text" name="username"/><br>
<label>密码:label><input type="password" name="password" /><br>
<label>确认密码:label><input type="password" name="password2"/> <br>
<input type="submit" value="提交"> <br>
form>
html>
实现效果如下:
1.2 编写 Python 的后台逻辑处理
实现一个简单的登录逻辑处理
- 路由需要有 get 和 post 两种逻辑处理 判断请求方式
- 获取请求的参数 (flask 中 提供 request 函数 )
- 判断参数是否填写 以及 密码是否相同 (参数验证)
- 如果判断都没有问题,就返回一个 success
出问题,将问题返回到游览器
代码语言:javascript复制from flask import Flask
from flask import render_template,request,flash
app = Flask(__name__)
'''
消息闪现,向网页发送内容
给模板传递消息
flash (需要加密) 需要设置 secret_key
模板中需要遍历消息
'''
app.secret_key = "ali" # 设置一个 secret_key,才可以使用 消息闪现的功能
@app.route("/", methods=['GET','POST'])
def index():
# request 是一个请求对象 -> 获取请求方式,数据
#1. 判断请求方式
if request.method == 'POST':
#2、获得请求参数
username = request.form.get('username')
password = request.form.get('password')
password2 = request.form.get ('password2')
print(username,password,password2)
# 3、验证
if not all([username,password,password2]):
print('参数不完整')
# 编码问题加一个 u
flash(u"参数不完整")
elif password != password2:
print("密码不一致")
flash(u"密码不一致")
else:
return "success"
return render_template("index.html")
if __name__ == '__main__':
app.run(host="127.0.0.1",debug=True,port=3000)
我们需要使用到 消息闪现的功能,把信息发送到 前端中,所以前端代码需要修改一下,在 from 下面加上如下的一段 jinjia2 语句
代码语言:javascript复制 {# 使用遍历,获取闪现的消息 #}
{% for message in get_flashed_messages(): %}
{{ message }}
{% endfor %}
1.3 运行效果
- 直接提交
- 两次密码输入的不一致
- 验证成功
写了这么多,其实这些都是前面学习过的内容,今天来学习一下使用 Flask-wtf 来生成我们需要的表达那效果
二、 使用 Flask-WTF 扩展验证表单
使用 witf 创建表单,主要需要如下几步来完成
- 安装 flask-wtf:
pip install Flask-WTF
- 自定义一个表单类
- 然后渲染到 HTML 中
- 补充验证
- 验证需要导入验证函数
2.1 定义表单验证类
为了展示方便,我把表单类定义在同一个文件中
代码语言:javascript复制# 导入自定义表单需要的字段
from wtforms import StringField, PasswordField, SubmitField
# 导入 wtf扩展提供的表单验证
from wtforms.validators import DataRequired, EqualTo
class LoginForm(FlaskForm):
# 这里定义 每个字段,使用 StringField 表示字符串字段,PasswordField 代表密码字段, SubmitField 代表提交字段
# validators 表示数据验证, DataRequired 验证非空, EqualTo 验证数据是否相等
username = StringField(u"用户名", validators=[DataRequired()])
password = PasswordField(u"密码", validators=[DataRequired()])
password2 = PasswordField(u"确认密码", validators=[DataRequired(), EqualTo("password", "密码填入的不一致")]) # 和第一个比较相同
submit = SubmitField(u"提交")
2.2 编写前端界面
second.html
代码语言:javascript复制<html lang="en">
<head>
<meta charset="UTF-8">
<title>wtf 验证title>
head>
<body>
<form method="post">
{{ form.csrf_token() }}
{{ form.username.label }}:{{ form.username }} <br>
{{ form.password.label }}: {{ form.password }} <br>
{{ form.password2.label }}: {{ form.password2 }} <br>
{{ form.submit }}
form>
body>
html>
2.3 Flask 后台处理
代码语言:javascript复制@app.route('/form', methods=['POST','GET'])
def login():
login_form = LoginForm()
if request.method == 'POST':
username = request.form.get ('username')
password = request.form.get ('password')
password2 = request.form.get ('password2')
# 验证参数, wtf 可以一句话实现所有的校验
# 缺少 CRSF token会导致不通过,需要在 csrf 的东西
if login_form.validate_on_submit():
print(username, password)
return 'success'
else:
flash("参数有误")
# 往模板传值
return render_template('second.html',form=login_form)
2.4 验证
三、Python 操作数据库
Python 作为一门后端语言,它当然也可以操作数据库,本次操作均已 mysql 为例
如果你还不会 mysql,可以先看这篇文章:MySQL 常用命令一览
Python 操作 mysql 的库有很多,我这里选择使用 pymysql 来演示
3.1 安装 pymysql
应该可以安装的上,我使用虚拟环境的默认环境安装的
使用默认源安装:pip install pymysql
如果速度太慢,可以使用另一个方式:pip3 install pymysql -i https://pypi.douban.com/simple
3.2 配置数据库信息
以下两种方式均可使用
代码语言:javascript复制import pymysql
config = {
"host":"127.0.0.1",
"user":"root",
"password":"你的数据库密码",
"database":"bank"
}
# 方式一
db = pymysql.connect(**config)
# 方式二
db = pymysql.connect("localhost","root","数据库密码","db_name")
3.3 简单的数据库操作
代码语言:javascript复制import pymysql
config = {
"host":"127.0.0.1",
"user":"root",
"password":"root",
"database":"bank"
}
# 连接数据库
db = pymysql.connect(**config)
# 创建一个游标对象
cursor = db.cursor()
# 编写 SQL 语句
s = "select * from student"; # 因为查询不需要提交事务,所以我们可以直接获取数据
# 获取查询的数据
cursor.execute("select * from student") # 执行查询语句
data = cursor.fetchall()
# 获得的数据有多个就是个元组,所以需要循环打印数据
for i in data:
print(i)
# 如果你还想插入数据,可以这么做
cursor.execute(f"insert into student values({39},'gorit',{18},{97})")
db.commit() # 数据发生了变化,所以需要提交事务
pymysql 的基本操作就讲到这里,只要 sql 语句写的好,就可以使用 pymysql 来实现,而且效率还相对下边的 ORM 更高
四、使用 Flask-SQLAlchemy (ORM)操作数据库
- 我们需要用到 Flask-SQLAlchemy 这个扩展,所以我们需要安装它:
pip install Flask-SQLAlchemy
- 前提装好了 mysql 数据库
- 我们会用到 pymysql 的引擎操作数据库,所以这个也要安装上:pip install pymysql
4.1 创建实体类(建表)
- 创建一个 Test_sql.py 文件 (创建实体类,并用 该扩展生成相对应的表)
- 创建一个 Test_sql_config.cfg 的配置文件 (Flask 的属性配置文件)
- 创建一个 operate_new_sql.py 文件 (测试 ORM)
#!/usr/bin/python
# -*- coding: utf-8 --
#@File: Test_sql.py
#@author: Gorit
#@contact: gorit@qq.com
#@time: 2020/4/4 17:50
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
app = Flask(__name__)
app.config.from_pyfile ("Test_sql_config.cfg") # 把一些必要配置写进配置文件中
db = SQLAlchemy(app) # 实例化数据库,等会测试 ORM 会用到这个
# 创建学生表
class Student(db.Model):
tablename = "student"
# 主键
id = db.Column(db.Integer, primary_key = True) # 主键
name =db.Column(db.String(64), nullable=False) # 学生姓名,nullable 能否为空
gender = db.Column(db.Enum("男","女"), nullable=False) # 枚举,只能使用指定的数据,非空
phone = db.Column(db.String(11)) # 手机号 可以为空
# 创建课程表
class Course(db.Model):
tablename = "course"
id = db.Column(db.Integer, primary_key = True) # 主键
name = db.Column(db.String(64), nullable=False) # 课程名非空
# teacher_id = db.Column()
# 创建教师表
class Teacher(db.Model):
tablename = "teacher"
id = db.Column(db.Integer, primary_key = True) # 主键
name = db.Column(db.String(64), nullable=False) # 学生姓名,nullable 能否为空
gender = db.Column(db.Enum("男","女"), nullable=False) # 枚举,只能使用指定的数据,非空
phone = db.Column(db.String(11)) # 手机号 可以为空
# 创建成绩表
# class Grade(db.Model):
# tablename = "grade"
# id = db.Column(db.Integer, primary_key = True) # 主键
# course_id =
# grade =
# student =
if __name__ == '__main__':
db.create_all()
为什么我要把配置文件单独抽出来,因为不这么做的话,我就得在 FLask 的文件中一个个的使用 app.config‘xxxxx’ = xxxx,会很麻烦,因此把这些内容全部方法文件之中
代码语言:javascript复制JSON_AS_ASCII = False # 返回 json 数据时,关闭转 ASCLL 码
DEBUG = True # 调试模式打开
SECRET_KEY = "sb_3306o233" # 使用消息闪现必须要配置的内容
# 数据库的配置
SQLALCHEMY_DATABASE_URI = "mysql pymysql://root:root@localhost:3306/bank?charset=utf8" # 这里的 pymysql 是使用它的引擎操作 pymysql。剩下的按照顺序就是账号,密码。服务的 URI 端口,数据库,字符集等等内容
SQLALCHEMY_COMMIT_ON_TEARDOWN= False # 数据库的配置
SQLALCHEMY_TRACK_MODIFICATIONS = True # 数据库的配置
4.2 单表操作之 —— 增加数据
接下来的数据库操作部分均在 operate_new_sql.py 文件中完成
代码语言:javascript复制#!/usr/bin/python
# -*- coding: utf-8 --
#@File: operate_new_sql.py
#@author: Gorit
#@contact: gorit@qq.com
#@time: 2020/4/4 20:07
# 操作数据库
from Test_sql import db, Student
# db 为实例化的数据库操作对象, Student 为一张表
# ================== 单表增
# 创建学生对象
# 创建好后 id 会自增
s = Student(name="666", gender="女", phone="13324436542")
s1 = Student(name="xxx", gender="女", phone="13324426542")
s2 = Student(name="xxx", gender="男", phone="18324426542")
# 语句 第一种(一次增加一条数据)
# db.session.add(s)
# db.session.commit()
# 语句 第二种(一次性添加多条数据)
db.session.add_all([s1,s2,s])
db.session.commit()
4.3 单标操作之 —— 查询数据
代码语言:javascript复制# ========================= 单标查
# get 第一种查询, 查询单一的一个
# stu = Student.query.get(1) # 放入的是 id,根据主键查询 局限性很大
# print(stu.name, stu.gender, stu.phone) # stu 是一个学生类对象,所以会直接打印对象
# all() 查询全部
# stu1 = Student.query.all()
# for i in stu1:
# print (i.name, i.gender, i.phone)
# filter() 按照条件查询
# stu = Student.query.filter(Student.id <=5)
# stu = Student.query.filter(Student.name == "张三")
# stu = Student.query.filter(Student.gender == "女")
# for i in stu:
# print (i.name, i.gender, i.phone)
# filter_by() 类似 sql 查询 first() 查询第一个
# stu = Student.query.filter_by(name="张三")
# stu = Student.query.filter_by(name="张三").all() 打印对象
# stu = Student.query.filter_by(name="张三").first()
# print(stu)
上面的可以看出,我们只能做简单的查询,如果高级一点,分组查询,子查询等等,就可能难以实现,所以还是 乖乖的好好学 sql 语句吧,hhhhhh
4.4 单表操作之 —— 修改数据
我们这里接收得到的都是被修改的数据的数量
代码语言:javascript复制# =========================== 单表改
# 第一种
# 修改一条数据
count = Student.query.filter(Student.name == "张三").update({"name":"张一"})
print(count) # 返回的是修改了多少条数据
db.session.commit()
print(stu.name, stu.gender, stu.phone)
# 第二种
stu = Student.query.filter(Student.gender == "男").update({"gender":"女"})
print(stu) # 得到是个整数
db.session.commit()
# 批量修改
stu1 = Student.query.filter(Student.gender == "女").all()
for i in stu1:
i.gender = "男"
db.session.add(i)
db.session.commit()
4.5 单表操作之 —— 删除数据
将查询的数据删除即可
代码语言:javascript复制# 单表删
stu = Student.query.filter(Student.gender == "女").delete()
print(stu) # 返回 0
db.session.commit()
4.6 小总结
单表数据的增删查看
- 增加数据 add 和 commit
- 查询 不需要 commit
- 需要都要 commit
- delete 也需要 commit