在《Sanic框架介绍》一节中的简单示例中,路由函数test()
有一个参数request
,它是一个Request
对象,包含了客户端(浏览器)发过来的HTTP请求的各类数据。
Sanic Request
对象的属性
(1)json
:JSON格式数据
当客户端POST来的数据是json格式时,可以通过request.json
来访问:
from sanic import response
@app.route('/json', methods=['POST'])
async def post_json(request):
return response.json({"received": request.json})
(2)args
(字典):查询字符串变量
查询字符串变量就是说URL中问号?
及其后面的部分,比如,?name=jim&age=12
。这样带查询变量的URL被解析后,args
字典就是这样的:{'name':['jim'], 'age': ['12']}
。request对象的属性query_string
就是未解析的字符串值:name=jim&age=12
。该属性提供了默认的解析查询变量的策略,稍微我们介绍如何改变解析策略。
from sanic import response
@app.route('/args')
async def args(request):
return response.json({
"parsed": True,
"args": request.args,
"url": request.url,
"query_string": request.query_string,
})
(3)query_args
(列表)
该属性提供了另外一种url参数的形式,它是元组(key, value)
的列表。该属性提供了默认的解析查询变量的策略,稍微我们介绍如何改变解析策略。
对于前面的URL查询变量?name=jim&age=12
,对应的query_args
列表就是:
[('name', 'jim'), ('age', '12')]
如果同一个key对应多个value的情况?name=jim&age=12&name=tom
,对应的query_args
就是:
[('name', 'jim'), ('age', '12'), ('name', 'tom')]
Sanic 18.12 版本已经没有 query_args 这个属性
下面看具体代码来理解args
等查询变量:
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route('/args')
async def test(request):
return json({
"parsed": True,
"url": request.url,
"query_string": request.query_string,
"args": request.args,
"raw_args": request.raw_args,
# "query_args": request.query_args,
})
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888)
访问这个web应用的输出是:
{
"parsed": true,
"url": "http://127.0.0.1:8888/args?name=jim&age=12&name=tom",
"query_string": "name=jim&age=12&name=tom",
"args": {
"name": [
"jim",
"tom"
],
"age": [
"12"
]
},
"raw_args": {
"name": "jim",
"age": "12"
}
}
注意 raw_args
字典的value不是列表,而是args
字典中value的第一个值。这个属性将来会被弃用。
(4)files
(字典):拥有name、body和type的文件对象的字典
客户端(浏览器)上传的文件包含在Form data中,files
字典的key是Form对象中文件对象的名称(不是文件名),这个文件对象有name(文件名)、body(文件数据)和type(文件类型)三个属性。
from sanic import Sanic
from sanic import response
app = Sanic()
@app.route('/')
async def index(request):
html = ('<html><body>'
'<form action="/files" method="post" enctype="multipart/form-data">'
'<input type="file" name="file1" /> <br />'
'<input type="file" name="file2" /> <br />'
'<input type="submit" value="Upload" />'
'</form>'
'</body></html>')
return response.html(html)
@app.route("/files", methods=['POST'])
async def post_json(request):
test_file = request.files.get('file1')
file_parameters = {
'body': len(test_file.body),
'name': test_file.name,
'type': test_file.type,
}
return response.json({
"received": True,
"file_object_names": request.files.keys(),
"test_file_parameters": file_parameters
})
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8888)
运行上面这个web应用,并用浏览器打开http://127.0.0.1:8888/
这个地址,可以看到一个简单的上传界面,需要选择两个文件,然后点击“Upload”,就可以看到这个web应用返回的json数据:
// 20190321203852
// http://127.0.0.1:8888/files
{
"received": true,
"file_object_names": [
"file1",
"file2"
],
"test_file_parameters": {
"body": 33759,
"name": "ft-generator.jpg",
"type": "image/jpeg"
}
}
注意 从结果可以看出,requests.files.keys()
是网页html中input
的name
,不是文件名。
(5)form
(字典):以POST方式传递的form变量
在上面files
例子中的网页html部分加一行:
<input type="text" name="title" /> <br />
在post_json()
函数的返回json里面加上request.form
,就可以看到request.form
的内容了:
{
"received": true,
"form": {
"title": [
"猿人学Python"
]
},
"file_object_names": [
"file1",
"file2"
],
"test_file_parameters": {
"body": 33759,
"name": "ft-generator.jpg",
"type": "image/jpeg"
}
}
(6)body
(字节串):POST的原始数据。
这个属性允许我们得到request的原始数据。
(7)headers
(字典):包含请求头(headers)的不区分大小写的字典。
(8)method
(字符串):HTTP请求的方法,比如GET, POST
等。
(9)ip
(字符串):客户端(浏览器)的IP地址。
(10)port
(字符串):客户端(浏览器)的端口地址。
(11)socket
(元组):客户端(浏览器)的(IP, port)
(12)app
:正在处理该request的Sanic应用对象的引用。当我们在blueprint文件里面或其它模块需要使用全局的app
时可以通过request.app
来访问它。
以下都是字符串属性:
(13)url
:请求的完整URL。
(14)scheme
:请求的URL scheme:http
或https
。
(15)host
:请求的host:127.0.0.1:8888
。
(16)path
:请求的路径path: 比如/files
。
(17)query_string
:请求的查询字符串,name=jim&age=12
或空字符串''
。
(18)uri_template
:路由处理器匹配的模板:/posts/<id>/
。
(19)token
授权header的值,,比如Basic YWRtaW46YWRtaW4=
。
Sanic Request使用get
和getlist
访问值
request的属性中是字典的,其实是dict
的一个子类RequestParameters
。它与内置字典不同的是get()
和getlist()
方法。
get(key, default=None)
跟dict
的get方法一样。如果value是list时,只返回list的第一个元素。getlist(key, default=None)
返回整个list。
from sanic.request import RequestParameters
args = RequestParameters()
args['titles'] = ['Post 1', 'Post 2']
args.get('titles') # => 'Post 1'
args.getlist('titles') # => ['Post 1', 'Post 2']
总结
request
对象是web应用要处理的对象,它包含了客户端(浏览器)的请求数据,通过它的各种属性来访问这些请求数据。

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。
***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***
说点什么吧...