外观
Flask请求
利用Flask提供的Request对象可以获取URL中问号后面的参数值也可以获取通过POST请求提交的表单中的值。
Request请求对象中封装了大部分请求报文,可以从中获取参数值。请求解析和响应大部分是由Werkzeug处理的,Flask子类化Werkzeug的请求和响应对象,并添加了和程序有关的特定功能。
Request对象的常用属性和方法如下表:
| 属性或方法 | 说明 |
|---|---|
| form | 一个字典,存储请求提交的所有表单字段 |
| args | 一个字典,存储通过URL查询字符传递的所有参数 |
| values | 一个字典,form和args的合集 |
| cookies | 一个字典,存储请求的所有cookie |
| headers | 一个字典,存储请求的所有http首部 |
| files | 一个字典,存储上传的所有文件 |
| get_data() | 返回请求主题缓冲的数据 |
| get_json() | 返回一个字典,包含解析请求主体后得到的JSON |
| blueprint | 处理请求的Flask蓝图的名称 |
| endpoint | 处理请求的Flask端点的名称 |
| method | HTTP请求方法,可以是GET或POST |
| scheme | URL方案(http或https) |
| is_secure() | 通过安全的连接(https)发送请求时,返回True |
| host | 请求定义的主机名,若客户端定义了端口号,则还包括端口号 |
| path | URL的路径部分 |
| query_string | URL的查询字符串部分,返回原始二进制值 |
| full_path | URL的路径和查询字符串部分 |
| url | 客户端请求的完整URL |
| base_url | 比较url减少了查询字符串部分 |
| remote_addr | 客户端的IP地址 |
| environ | 请求的原始WSGI字典 |
- 获取GET请求参数
使用request.args.get(arg)方法可以获取GET请求参数,其中arg为参数的名字。
如URL为127.0.0.1:5000?name=qi&password=123456,则request.args.get('name')的值就为'qi'。
由于这部分很简单,这里不用代码演示了。
- 获取POST请求参数
使用request.args.post(args)方法可以获取POST请求参数,或者使用request.form对象获取表单数据。
我在测试时没有找到request.args.post这个方法,可能在最新版本的模块中被删除了。
如我们创建一个run.py,然后在这个文件中定义一个默认路由,随后判断请求是否是以POST形式提交的,若否就渲染模板index.html,若是则获取表单中提交的姓名和年龄,然后在页面中输出这两个变量的值,代码如下。
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
name = request.form['name']
age = request.form['age']
return f'姓名:{name}, 年龄:{age}'
else:
return render_template('index.html')
if __name__ == '__main__':
app.run()然后我们创建一个模板文件index.html,在其中我们创建一个表单,让这个表单以post方式提交,接着创建姓名、年龄输入框和提交按钮,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<form method="post">
姓名:<input type="text" name="name"><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit">
</form>
</body>
</html>运行run.py文件后访问127.0.0.1:5000,在姓名中输入qi,在年龄中输入20,再点击提交,就可以看到输出结果为“姓名:qi,年龄:20”了。
- 文件上传
在使用Web表单时,经常使用文件上传的功能。使用request.files对象就可以获取与表单文件相关的数据。
如我们实现一个用户上传图片功能。首先定义一个路由函数upload(),用于上传图片,然后创建一个模板文件upload_file.html,用于显示上传文件的页面,最后编写一个show_file()函数,用于显示图片。
上传文件的模板文件upload_file.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传图片</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
上传文件:<input type="file" name="file"><br/>
<input type="submit">
</form>
</body>
</html>表单的enctype属性值要设为multipart/form-data,用于上传文件。
接下来创建run.py文件,在里面定义upload()路由函数,若接收请求为POST时就上传图片,若为GET请求就上传图片。图片上传完成后将页面重定向至图片路径,直接读取图片。
import os.path
import uuid
from flask import Flask, request, render_template, redirect, url_for, send_from_directory
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads' # 配置文件的上传路径
ALLOWED_EXTENSIONS = {'jpg', 'png', 'jpeg'} # 配置允许上传的文件名后缀
def is_file_allowed(filename): # 定义文件后缀是否符合格式的函数
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
def random_file_name(filename): # 定义随机命名文件名的函数
ext = os.path.splitext(filename)[1]
new_filename = uuid.uuid4().hex + ext
return new_filename
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET': # 若请求为GET则渲染模板
return render_template('upload_file.html')
elif request.method == 'POST': # 若请求为POST则执行上传功能且重定向至图片
pic = request.files['file'] # 读取表单中的图片
if pic and is_file_allowed(pic.filename): # 若成功读取且文件有效
filename = random_file_name(pic.filename)
pic.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # 保存图片
return redirect(url_for('uploaded_file', filename=filename)) # 重定向
else:
return '文件类型不支持'
@app.route('/uploads/<filename>') # 读取图片的路由
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
app.run()