请求对象
QueryDict 对象
QueryDict 对象是 django 中一种特殊类型的字典
里面可以存储 一对一类型的数据, 也可以存储 一对多类型的数据
这个对象一般用来存储浏览器传递过来的参数
我们可以默认把他看成是一个字典
但是它和一般的字典的不同之处在于:
-
一键 ===> 一值: QueryDict 这个字典可以调用 get( ) 函数来获取.
-
一键 ===> 多值: QueryDict 这个字典的获取方法:
- 如果获取一个值: QueryDict.get( key ) 获取的是所有值的最后一个.
- 如果获取多个值: QueryDict.getlist( key ) 获取这个键对应的所有值, 存放在列表中返回.
get( ):
根据一个 key 获取一个值
如果一个键同时拥有多个值将获取最后一个值
# 使用格式: QueryDict.get('键') # 或可写为: QueryDict['键'] # 例如 QueryDict.get('a') # 获取 a 所对应的一个值.
getlist( ):
根据一个 key 获取多个值
根据键获取对应的值,值以列表返回
可以获取指定键的所有值, 如果键不存在则返回空列表 [ ]
# 使用格式: QueryDict.getlist('键') # 例如 QueryDict.getlist('a') # 获取 a 所对应的所有值.
前端传参的四种方式
查询字符串传参 ( QueryString )
什么是查询字符串?
简单理解: url : http://www.itcast.cn:80/users/index/?a=1&b=2&c=3#id=123 url 地址中以 ? 开始,直到 # 结束的部分, 我们统称为: 查询字符串( QueryString ) 获取请求路径中的查询字符串参数(形如 ?k1=v1&k2=v2 )
获取查询字符串传递的参数
可以通过 request.GET 属性获取,这个方法返回 QueryDict 对象。
// 前端发送请求: $.ajax({ url:'http://127.0.0.1:8000/reqresp/qs/?a=1&b=2&a=3', type:'get', dataType:'json' }) .done(function(data){ console.log(data) // 打印: OK }) .fail(function(error){ console.log(error) })
# python 部分接收发送的参数并打印: # 视图函数 def qs(request): # 获取查询字符串参数 a = request.GET.get('a') b = request.GET.get('b') alist = request.GET.getlist('a') # 打印 print(a) # 3 print(b) # 2 print(alist) # ['1', '3'] # 返回响应对象 return HttpResponse('OK')
重要:
查询字符串不区分请求方式,即假使客户端进行 POST 方式的请求,依然可以通过 request.GET 获取请求中的查询字符串数据。
注意:
- 这里的 request.GET 指的不是发送 ajax 用的 get 方法, 而是指从 url 的查询字符串中获取参数
- 同理: request.POST 指的也不是 ajax 用的 post 方法,而是我们从请求体中获取的参数
- 通过上面大家就能明白: GET 和 POST 这里指的都是获取参数的位置, 而不是我们以前说的 get 请求和 post 请求.
总结:
- 如果前端传的参数是字符串类型, 可以通过 request.GET 来获取
- 通过 request.GET 获取的是 QueryDict 类型
- 我们可以通过 QueryDict 的 get( ) 和 getlist( ) 方法来获取对应的数据.
通过 URL 路径传参
在定义路由 URL 时,可以使用正则表达式提取参数的方法从 URL 中获取请求参数,Django 会将提取的参数直接传递到视图的传入参数中。
- 未命名参数按定义顺序传递
子路由则应该这样写: re_path(r'^weather/([a-z]+)/(\d{4})/$', views.weather),
对应的视图部分( views.py ):
def weather(request, city, year): '''定义weather函数, 接收路径参数''' print('city=%s' % city) print('year=%s' % year) return HttpResponse('OK')
- 命名参数按名字传递
子路由则应该这样写: 这里用到了python高级知识: 正则分组命名. re_path(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),
对应的视图部分( views.py ):
起名字的话, 我们在接收参数时, 可以更换参数位置. def weather(request, year, city): '''定义weather函数, 接收路径参数''' print('city=%s' % city) print('year=%s' % year) return HttpResponse('OK')
总结:
- 路径传参是前端发送参数的一种常用形式
- 把参数伪装成路径, 传递到后端
- 路径传参会在路径匹配的时候进行正则校验
- 路径传参分为未命名参数和命名参数
- 命名参数就是分别给参数起一个名字
- 未命名参数就是不给参数起名字
非表单类型传值 ( Non-Form Data )
非表单类型传值的方式:
非表单类型的请求体数据,Django 无法自动解析
可以通过 request.body 属性获取最原始的请求体数据,自己按照请求体格式( JSON、XML 等)进行解析。
其中: request.body 返回 bytes 类型。
# 获取方式: request.body # 得到的是 bytes 类型数据 # 可以通过 decode() 函数: 将 bytes 转为 str request.body.decode() # 可以通过 json.loads() 函数把 str 转为 dict json.loads(request.body.decode())
例如:
要获取请求体中的如下 JSON 数据
{"a": 1, "b": 2}
可以进行如下方法操作:
import json def get_body_json(request): '''定义一个函数,接收json数据''' # 获取 json 类型数据: json_bytes = request.body # 将 bytes 类型转为 str json_str = json_bytes.decode() # 将 str 转为 dict dict = json.loads(json_str) print(dict.get('a')) # 1 print(dict.get('b')) # 2 return HttpResponse('OK')
总结:
- 如果前端传递的是 json 类型的数据, 可以通过 request.body 类获取
- 获取到的数据是 bytes 类型, 所以我们需要将其解码为 str 类型
- 另外, 转为 str 后, 如果需要转为 dict, 则需要调用 json.loads( ) 函数
请求对象中的请求头信息
获取请求头数据
可以通过 request.META 属性获取请求头中的数据 request.META 为字典类型
这里需要注意一点是: 我们平常见到的请求头是这样的:
POST /reqresp/req/ HTTP/1.1 Host: 127.0.0.1:8000 Content-Type: application/x-www-form-urlencoded Cache-Control: no-cache Postman-Token: dd531a45-7518-1e8f-63a5-be03ed593471 a=1&b=2&a=3
但是我们通过 request.META 获取的时候,需要使用如下所示的用法:
CONTENT_LENGTH – The length of the request body (as a string). CONTENT_TYPE – The MIME type of the request body. HTTP_ACCEPT – Acceptable content types for the response. HTTP_ACCEPT_ENCODING – Acceptable encodings for the response. HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response. HTTP_HOST – The HTTP Host header sent by the client. HTTP_REFERER – The referring page, if any. HTTP_USER_AGENT – The client’s user-agent string. QUERY_STRING – The query string, as a single (unparsed) string. REMOTE_ADDR – The IP address of the client. REMOTE_HOST – The hostname of the client. REMOTE_USER – The user authenticated by the Web server, if any. REQUEST_METHOD – A string such as "GET" or "POST". SERVER_NAME – The hostname of the server. SERVER_PORT – The port of the server (as a string).
具体使用如:
def get_headers(request): # 使用字典的方式获取请求头内部的数据 print(request.META['CONTENT_TYPE']) # 返回 return HttpResponse('OK')
总结:
- 通过 request.META 属性我们可以获取请求对象的所有请求头信息
- request.META 是一个字典
- 从 request.META 中获取数据时, key 值需要大写