flask的一些插件flask_wtf&flask-mysqldb数据库的使用
flask_wtf
flask_wtf是flask框架的表单验证模块,可以很方便生成表单,也可以当做json数据交互的验证工具,支持热插拔。
安装
pip install flask_wtf
常用字段说明:
字段 | 说明 | 举例 |
---|---|---|
BooleanField | 布尔类型 | 如Flask,True |
StringField | 字符串类型 | 如:asdfghjk |
DecimalField | 小数点文本字段 | 如:‘1.23’ |
DateField | 日期字段 | 格式:’%Y-%m-%d’ |
DateTimeField | 日期字段 | 格式:’%Y-%m-%d %H:%M:%S’ |
FieldList | 统一字段类型组成列表 | 如:FieldList(StringField(‘Name’, [validators.required()])) |
FloatField | 浮点数类型 | 1.11 |
IntegerField | 整形 | 12 |
SelectMultipleField | 多选框 | |
RadioField | 单选框 | |
TextAreaField | 文本域 | 可接受多行输入 |
PasswordField | 密码字段 | 输入的不会直接在浏览器明文显示 |
FileField | 上传文件 | 但不会处理验证文件,需要手动处理 |
HiddenField | 隐藏字段 | |
SubmitField | 按钮 | |
TextField | 字符串类型的别名,弃用 |
常用的验证函数
模块中大小写有对应的方式,如DataRequired对应data_required。
字段函数 | 说明举例 |
---|---|
DataRequired / data_required | 验证数据是否真实存在,即不能为空,必须是非空白字符串,否则触发StopValidation错误。 |
InputRequired / input_required | 和DataRequired的区别在于可以是空白字符串; |
Required / required | data_required的别名 |
Email / email | 验证符合邮件的格式,只有最基本的验证; |
EqualTo / equal_to | 比较两个字段的值,比如密码和确认密码,如果不相等就触发错误 |
equal_to(field,message) | 需要输入另一个字段的名字。 |
IPAddress / ip_address | 验证是否是ip地址,默认验证IPV4地址。 |
MacAddress / mac_address | 验证是否符合mac格式; |
UUID | 是否是uuid格式; |
URL / url | 验证是否符合url格式; |
Regexp / regexp | 用提供的正则表达式验证字段;Regexp(r"") |
Length / length | 设置字段值的长度,Length(min,max); |
NumberRange / number_range | 设置一个数字字段的取值范围,可以针对浮点数和小数;NumberRange(min,max) |
Optional / optional: | 字段为空并停止验证; |
NoneOf / none_of | 将传入的数据和无效的比较,是抛出异常;Noneof(values). |
Anyof / any_of | 将传入的数据和预设的数据比较,不是异常。Anyof(values). |
表单对象
对象 | 解释 |
---|---|
FlaskForm | 内部定义了一个Meta类,该类添加csrf保护的一些方法,所以创建表单的时候一定要导入FlaskForm而不是Form. |
is_submitted | 检查是否有一个活跃的request请求; |
validate_on_submit | 调用is_submitted和validate方法,返回一个布尔值,用来判断表单是否被提交; |
validate | 字段级别的验证,每个字段都有一个validate方法,FlaskForm调用validate会对所有的字段调用validate方法验证,如果所有的验证都通过返回Ture,否则抛出异常。 |
hidden_tag | 获取表单隐藏的字段; |
wrap_formdata | 获取request中的form,每次form对象初始化时会执行该函数从request获取form。 |
数据库连接
安装数据库
flask sqlalchemy 是基于sqlite3的是orm的一种构架,大部分语法和sqlite3有些类似。简单介绍一下什么是数据库: 正规点的定义就是:数据库是长期存储在计算机内,大量有组织可共享的数据的集合。简单点就是,比如你有一个database(数据库),数据库中有很多表格,就像excel那样子。 表格中有每一列的名字(字段),用来标记每一列是存的什么信息。就这么简单,当然数据还会有些特殊的属性,比如primary key, unique, not null等等。
安装数据库和ORM框架:
pip install flask-sqlalchemy
pip install flask-mysqldb
创建一个连接对象
from flask_sqlalchemy import SQLAlchemy
# 创建一个管理数据库对象,注意参数需要和app产生联系,
db = SQLAlchemy(app)
创建模型
创建用户类
class User(db.Model):
#定义表名
__tablename__ = 'User'
#定义字段
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(20),unique=True)
is_delete = db.Column(db.Boolean,default=False)
email = db.Column(db.String(30),nullable=True)
# 这个是返回可读字符串
def __repr__(self):
return self.name
进行数据库表的创建
#删除自己所在表数据
db.drop_all()
#数据库迁移
db.create_all()
插入数据
obj1 = User(name='校长')
obj2 = User(name='小贝')
obj3 = User(name='小花')
obj4 = User(name='校民',email='123@qq.com')
#添加到数据库
db.session.add(obj1) #插入一条
db.session.add_all([obj1,obj2,obj3,obj4]) #插入多条
#确认提交数据
db.session.commit()
查询数据
精准查询 filter_by
Users.query.filter_by(name='校长').all() #查询名字为校长的用户
Users.query.first()#查询第一条
模糊查询 filter
Users.query.filter(Users.name.startswith('张').all() #查询姓'张'的用户
Users.query.filter(Users.name.endswith('三').all() #查询名字最后为'三'的用户
查询所有对象
Users.query.all()
get 方法的使用
>>>Users.query.filter(not_(Users.name=='李三')).all()
>>>
注意点:
1.get()这个方法的参数必须是一个主键
2.如果主键不存在,没有返回值
not_ 取反操作
查询名字不是张三的用户
from sqlalchemy import not_
Users.query.filter(not_(Users.name=='张三')).all()
注意点:
1.导包
2.相当于取反
and_ 逻辑与 操作
查询名字最后一个字带黄的并且email=='783@qq.com的用户
from sqlalchemy import and_
Users.query.filter(and_(Users.name.endswith('黄'),Users.email=='783@qq.com')).all()
注意点:
1.导包
2.and_()括号中可以有多个条件,但是多个条件之间必须全部成立
or_ 逻辑或 操作
查询姓张的或者email=='1234@qq.com的用户
from sqlalchemy import or_
Users.query.filter(or_(Users.name.startswith('张'),Users.email=='1234@qq.com')).all()
注意点:
1.导包
2.or_()括号中有多个条件,但是只要满足任意一个就行
一对多关系查询
查询出id=2的这个角色对应的用户
>>> Users.query.filter_by(role_id=2).all()
[<Users 黄忠>, <Users 高渐离>]
>>> role = Role.query.get(2)
>>> role.users
[<Users 黄忠>, <Users 高渐离>]
>>>
一对多反向引用
查询出id=2的这个角色对应的用户(这里是正向查询)
>>> users_obj = Users.query.get(2)
>>> users_obj.role_id
2
>>> users_obj = Users.query.get(2)
>>> users_obj.name
'高渐离'
在 xx.py 中添加反向引用
#在主表加关系,与用户表产生联系,代表的是这个角色下面所有的用户
# 用到的时候加载关联对象
users = db.relationship('Users',backref='role')
使用反向引用
查询当前用户对应的角色
>>> users_obj = Users.query.get(2)
>>> users_obj.role
<Role 管理员>
删除
查询id=2,并且删除
user = Users.query.get(2)
db.session.delete(user)
db.session.commit()
更新
查询id=1,并修改email为123@qq.com
user = Users.query.get(1)
user.email = '123@qq.com'
db.session.commit()
综合使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
{{ form.username.label }}{{ form.username }}<br>
{{ form.pwd.label }}{{ form.pwd }}<br>
{{ form.cpwd.label }}{{ form.cpwd }}<br>
{{ form.submit }}
</form>
</body>
</html>
创建.py文件
from flask import Flask,render_template,request
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField,PasswordField
from wtforms.validators import DataRequired,EqualTo,Length,NumberRange
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
# manager = Manager(app)
#生成秘钥
app.secret_key = os.urandom(24)
# #用于连接数据库的URI 数据库类型 账号密码 ip 端口 数据库名
app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:mysql@127.0.0.1:3306/flask'
# 创建一个管理数据库对象,注意参数需要和app产生联系
db = SQLAlchemy(app) #SQLAlchemy语言的映射关系
# 创建用户类
class User(db.Model):
#定义表名
__tablename__ = 'User'
#定义列对象
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(20),unique=True)
is_delete = db.Column(db.Boolean,default=False)
email = db.Column(db.String(30),nullable=True)
# 这个是返回可读字符串
def __repr__(self):
return self.name
#设置form表单
class Register(FlaskForm):
# 用户名,分别验证为必须字段,长度,以及额外设置属性
username = StringField(label='用户名',validators=[DataRequired()],render_kw={'placeholder':'请输入用户名'})
# 密码
pwd = PasswordField(label='密码', validators=[DataRequired()])
# 确认密码
cpwd = PasswordField(label='确认密码', validators=[DataRequired(), EqualTo('pwd','两次密码不一致'),Length(6,20)])
#提交
submit = SubmitField('提交')
@app.route('/index',methods=['POST','GET'])
def index():
#form表单实例化
register_form = Register()
#进行判断提交的时候是否满足提交条件
if register_form.validate_on_submit():
name = register_form.username.data
pwd = register_form.pwd.data
print('用户名',name,'密码',pwd)
return '注册成功'
else:
if request.method == 'POST':
return '校验未通过'
return render_template('temp1.html',form= register_form)
if __name__ == '__main__':
#删除自己所在表数据
# db.drop_all()
#数据库迁移
# db.create_all()
obj1 = User(name='校长')
obj2 = User(name='小贝')
obj3 = User(name='小花')
obj4 = User(name='校民',email='123@qq.com')
obj5 = User(name='聂离', email='123@qq.com')
obj6 = User(name='陆漂', email='1234@qq.com')
obj7 = User(name='江流儿', email='1235@qq.com')
obj8 = User(name='盖聂', email='1236@qq.com')
obj9 = User(name='卫庄', email='1237@qq.com')
obj10 = User(name='西蒙', email='1238@qq.com')
obj11 = User(name='大卫', email='1239@qq.com')
#添加到数据库
db.session.add_all([obj1,obj2,obj3,obj4])
#确认提交数据
db.session.commit()
app.run(debug=True)