Flask 初步学习
Flask程序的基本构造
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('demo.html')
if __name__ == '__main__':
app.run()
路由器请求方法限定
在route的参数中设置method的值,默认是GET方法
@app.route('/', methods=['GET', 'POST'])
def index():
return render_template('demo.html')
可以使用postman软件进行测试路由方式
动态路由
@app.route('/user/', methods=['GET', 'POST'])
def user(name):
return 'hello {}'.format(name)
其中参数可以通过类型进行限定,ex:int:name
Jinja2模板引擎
动态网页,可能有部分内容数据是需要计算出来的,是动态的内容
在函数中传递参数,在HTML页面中,利用{{}}获取传递的参数
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/user', methods=['GET', 'POST'])
def user():
user_var="程序设计类辅助实验教学平台"
return render_template('demo3.html', html_var=user_var)
if __name__ == '__main__':
app.run()
demo3.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>This is a Demo3 Page</h1>
<h2>It is only using for test</h2>
这是传输过来的变量:{{ html_var }}
</body>
</html>
显示效果:
在模板中使用{# This is a annotation #}进行注释
传参时,列表和字典的使用:
app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def user():
user_var="程序设计类辅助实验教学平台"
list_test=['这是list的1','这是list的2','这是list的3','这是list的4','这是list的5']
dict_test={
'name': "这是测试name",
'key': "这是测试key"
}
return render_template('demo3.html', html_var=user_var,list_test=list_test,dict_test=dict_test)
if __name__ == '__main__':
app.run()
demo3.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>This is a Demo3 Page</h1>
<h2>It is only using for test</h2>
这是传输过来的变量:{{ html_var }}<br>
<h2>列表使用:</h2>
{{ list_test }}<br>
{{ list_test.1 }}<br>
{{ list_test[2] }}<br>
<h2>dict使用:</h2>
{{ dict_test }}<br>
{{ dict_test.name }}<br>
{{ dict_test['key']}}<br>
</body>
</html>
页面效果:
控制语句
在{% %}中进行写控制语句
{% for num in list_test %}
{% if num > 2 %}
{{ num }}<br>
{% endfor %}
过滤器的基本使用
常见的过滤器
过滤器名
|
说明
|
safe
|
渲染时不转义
|
capitalize
|
把值的首字母大写,其余小写
|
lower
|
把值转换成小写形式
|
upper
|
把值转换成大写形式
|
title
|
把值中每个单词的首字母都转换成大写
|
trim
|
把值的首位空格去掉
|
striptags
|
渲染之前把值中所有的HTML标签删掉
|
web表单
使用Flask-WTF扩展
使用flash传递消息
app.py
from flask import Flask,render_template,request,flash
app = Flask(__name__)
app.secret_key='this is a secret key'
@app.route('/', methods=['GET', 'POST'])
def user():
#request请求对象,包括请求方式,数据等
#flash需要对内容加密,因此要设置secret_key,做加密消息混淆
if request.method == 'POST':
username=request.form.get('username')
password1=request.form.get('password1')
password2=request.form.get('password2')
if not all([username,password1,password2]):
#return '参数不完整'
flash('参数不完整')
elif password1 == password2:
#return 'true'
flash("true")
else:
#return 'false'
flash("false")
return render_template('demo3.html')
if __name__ == '__main__':
app.run()
demo3.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<label>用户名:</label><input type="text" name="username"><br>
<label>密码:</label><input type="password" name="password1"><br>
<label>确认密码:</label><input type="password" name="password2"><br>
<input type="submit" value="提交"><br>
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</form>
</body>
</html>
显示效果:
使用WTF实现web表单
WTForms支持的HTML标准字段
字段类型
|
说明
|
BooleanField
|
复选框,值为True和False
|
DateField
|
文本字段,值为datetime.date格式
|
DareTimeField
|
文本字段,值为datetime.datetime格式
|
FileField
|
文件上传字段
|
HiddenField
|
隐藏的文本字段
|
MultipleFileField
|
多文本上传字段
|
FieldList
|
一组指定类型的字段
|
FloatField
|
文本字段,值为浮点数
|
FormField
|
把一个表单作为字段嵌入另一个表单
|
IntegerField
|
文本字段,值为整数
|
PasswordField
|
密码文本字段
|
RadioField
|
一组单选按钮
|
SelectField
|
下拉列表
|
SelectMultipleField
|
下拉列表,可选择多个值
|
SubmitField
|
表单提交按钮
|
StringField
|
文本字段
|
TextAreaField
|
多行文本字段
|
WTForms验证函数
验证函数
|
说明
|
DateRequired
|
确保转换类型后字段中有数据
|
Email
|
验证电子邮件地址
|
EqualTo
|
比较两个字段的值,常用于要求输入两次密码进行确认的时候
|
InputRequired
|
确保转换类型前字段中有数据
|
IPAddress
|
验证IPv4网络地址
|
Length
|
验证输入字符串的长度
|
MacAddress
|
验证MAC地址
|
NumberRange
|
验证输入的值在数字范围之内
|
Optional
|
允许字段中没有输入,将跳过其他验证函数
|
Regexp
|
使用正则表达式验证输入值
|
URL
|
验证URL
|
UUID
|
验证UUID
|
AnyOf
|
确保输入值在一组可能的值中
|
NoneOf
|
确保输入值不在一组可能的值中
|
Flask-WTF扩展的安装
在PyCharm中打开Preferences
打开Project选项板
进行Project Interpreter设置
点击添加‘+’,然后搜索Flask-WTF
选择好版本之后,Install Package,拓展包就添加完成了
在项目中导入Flask-WTF
在项目中导入Flaks-WTF的HTML标准字段
from wtforms import StringField,PasswordField,SubmitField
在项目中导入Flask-WTF的验证函数
from wtforms.validators import DataRequired,
在使用Flask-WTF拓展的时候,需要使用CSRF Token
在html页面中加入
{{ html_form.csrf_token() }}
使用Flask-WTF创建表单示例
app.py
from flask import Flask, render_template, request, flash
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo
app = Flask(__name__)
app.secret_key = "dsauhfabf"
class LoginForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired()])
password1 = PasswordField('密码', validators=[DataRequired()])
password2 = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password1', "两次密码填入不一致")])
submit = SubmitField('提交')
@app.route('/form', methods=['GET', 'POST'])
def login():
login_form = LoginForm()
if request.method == 'POST':
username = request.form.get('username')
password1 = request.form.get('password1')
password2 = request.form.get('password2')
if login_form.validate_on_submit():
return 'success'
else:
flash("false")
return render_template('demo3.html', html_form=login_form)
if __name__ == '__main__':
app.run()
demo3.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<br>
{{ html_form.csrf_token() }}
{{ html_form.username.label }}{{ html_form.username }}<br>
{{ html_form.password1.label }}{{ html_form.password1 }}<br>
{{ html_form.password2.label }}{{ html_form.password2 }}<br>
{{ html_form.submit }}<br>
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</form>
</body>
</html>
页面效果:
Flask-SQLAlchemy拓展
使用Flask-SQLAichemy可以处理Python对象,而不是数据实体
安装方法:
- 通过PyCharm的project interpret 继续安装
- 通过命令行进行安装
在Flask-SQLAlchemy中,数据库使用URL进行指定,MySQL的URL格式为:
mysql://username:password@hostname/datebase
例如 mysql://root:password@127.0.0.1:3306/demoDatabse
安装pymysql
pip install pymysql
配置数据库:
from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI']= 'mysql+pymysql://root:password@127.0.0.1:3306/Demo'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
创建数据库类,映射数据库表
class ClassInfo(db.Model):
__tablename__ = 'classinfo'
id = db.Column(db.Integer(), primary_key=True)
className = db.Column(db.String(20))
classSize = db.Column(db.Integer())
注意,其中的类型的第一个字母要大写
在视图中操作数据库查询
通过数据库类的query对象中的方法进行查询
mylist = ClassInfo.query.all()
print(mylist)
for it in mylist:
print(it)
test = mylist[0].className
return render_template('demo3.html', html_form=login_form, test=test)
常用的SQLAlchemy查询过滤器
过滤器
|
说明
|
filter()
|
把过滤器添加到原查询上,返回一个新查询
|
filter_by()
|
把等值过滤器添加到原查询上,返回一个新查询
|
limit()
|
使用指定的值限制原查询返回的结果数量,返回一个新查询
|
offset()
|
偏移原查询返回的结果,返回一个新查询
|
order_by()
|
根据指定条件对原查询进行排序,返回一个新查询
|
group_by()
|
根据指定调教对原查询结果进行分组,返回一个新查询
|
常用SQLAlchemy查询执行方法
方法
|
说明
|
all()
|
以列表形式返回查询的所有结果
|
first()
|
返回查询的第一个结果,如果没有结果,则返回None
|
first_or_404()
|
返回查询的第一个结果,如果没有结果,则终止请求,返回4040错误响应
|
get()
|
返回指定主键对应的行,如果没有对应的行,则返回NOne
|
get_or_404
|
返回指定主键对应的行,如果没找到指定的主键,则终止请求,返回404错误响应
|
count()
|
返回查询结果的数量
|
paginate()
|
返回一个Paginate对象,包含指定范围内的结果
|
注册、登录
使用werkzeug计算密码散列值
werkzeug中的security模块实现了密码散列值的计算。共有两个函数
generate_password_hash(password, method=‘pbkdf2:sha256’, salt_length=8)
这个函数的输入为原始密码,返回密码散列值的字符串形式,供存入用户数据库。
check_password_hash(hash,password)
这个函数的两个参数为,数据库中存放的密码hash值,和用户输入的密码,如果一致,返回True,如果不一致,返回False。
文件的上传、下载
上传文件
html代码:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<div>
<form action="" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>
选择你需要上传的文件
</td>
<td>
<input type="file" name="file">
</td>
<td>
<input type="submit">
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
要注意,在中要设置属性enctype="multipart/form-data"
在后台接收文件并保存
在后台接受文件使用
uoload_file = request.files.get('file')
进行获取,get(‘’)中参数是前端页面中的input的name
在后台保存文件
可以使用save()进行保存
upload_file = request.files.get('file')
file_path = 'store'
wenjian.save(os.path.join(file_path,upload.filename))
可以secure_filename()生成随机文件名,在werkzeug.utils中,也可以手动设置文件名,加安全性
蓝图
Flask 蓝图
蓝图的作用是使Flask项目更加的模块化,结构更清晰。可以将相同的模块视图函数放在同一个蓝图下,同一个文件中,方便管理。
蓝图的基本用法
user_bp = Blueprint('user',__name__)
- 在主app文件中注册蓝图:
例如user_bp蓝图在Blueprint/user.py文件中,注册函数为下
from flask import Flask
from flask import Blueprint
from Blueprint.user import user_bp
app = Flask(__name__)
app.register_blueprint(user_bp)
- 给每个蓝图添加前缀
要给某个蓝图下的所有route添加各自的前缀,可以在初始化蓝图的时候设置:例如给user_bp的每个route前添加/user前缀
from flask import Blueprint
user_bp = Blueprint('user',__name__,url_prefix='/user')