DRF之请求与响应
【三】请求与响应
【1】请求
【1.1】Request对象
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None)
关键字参数:
- request(HttpRequest). 原始请求实例。
- parsers(list/tuple). 用于解析请求内容的解析器。
- authenticators(list/tuple). 用于尝试验证请求用户身份的验证器。
- negotiator(None). 协商者,用于内容协商。
- parser_context(None). 解析器上下文,用于解析器的上下文信息。
【1.1.1】常用属性
-
.data
-
request.data
返回解析之后的请求体数据。类似于Django中标准的request.POST
和request.FILES
属性,但提供如下特性:-
包含了解析之后的文件和非文件数据
-
包含了对POST、PUT、PATCH请求方式解析后的数据
-
利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
-
-
-
.query_params
request.query_params
与Django标准的request.GET
相同,只是更换了更符合restful规范的名称,搜索参数
【1.2】Parser解析器
- REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到Request对象中
- Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。
- 无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。
【1.2.1】三种解析器模块
模块 | 描述 | 请求编码格式 |
---|---|---|
JSONParser | 用于解析 JSON 请求内容。request.data 将被填充为一个数据字典。 |
application/json |
FormParser | 用于解析 HTML 表单内容。request.data 将被填充为一个数据 QueryDict。通常与 MultiPartParser 一起使用以完全支持 HTML 表单数据。 |
application/x-www-form-urlencoded |
MultiPartParser | 用于解析多部分 HTML 表单内容,支持文件上传。request.data 和 request.FILES 将分别被填充为一个 QueryDict 和 MultiValueDict。通常与 FormParser 一起使用以完全支持 HTML 表单数据。 |
multipart/form-data |
【1.2.2】默认配置
- 默认配置中,三种解析器均被配置,所以当我们使用任意一种编码格式均可以被解析为
request.data
【1.2.3】局部使用
- 当我们想要指定某个视图的请求只可以使用某种编码格式传输,就可以指定
# 导入模块
from rest_framework.parsers import JSONParser, FormParser
class TaskView(APIView):
# 当我们指定使用的解析器 # 请求将只能正确的解析出json和urlencoded编码格式的请求
parser_classes = [JSONParser, FormParser]
def get(self, request):
ser = TaskSer(Task.objects.all(), many=True)
return Response(ser.data)
【1.2.4】全局使用
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
]
}
【2】响应
【2.1】Response对象
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
参数:
- data:要返回的数据。默认为 None。
- status:响应状态码。默认为 None。
- template_name:模板名称,已弃用。改用 data 参数。默认为 None。
- headers:响应头信息。默认为 None。
- exception:是否为异常响应。默认为 False。
- content_type:响应内容类型。默认为 None。
【2.1.1】常用属性
.data
- 传给response对象的序列化后,但尚未render处理的数据
.status_code
- 状态码的数字
.content
- 经过render处理后的响应数据
【2.2】Renderer 渲染器
- REST framework提供了
Renderer
渲染器,用来根据请求头中的Accept
(接收数据类型声明)来自动转换响应数据到对应格式。 - 如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式
【2.2.1】两种渲染器模块
模块 | 描述 |
---|---|
JSONOpenAPIRenderer | 用于将 API 数据渲染为 OpenAPI(前身为 Swagger)规范的 JSON 格式 |
BrowsableAPIRenderer | 用于将 API 数据渲染为可浏览的 HTML 页面。它为 API 提供了一个交互式的界面,用户可以在浏览器中直观地浏览和测试 API |
【2.2.2】默认配置
-
默认配置中,两种渲染器都被配置了,所以我们可以在浏览器和postman中看到不同的界面
-
【注】当注册了
rest_framework
后,前端界面将会被美化 -
当只设置json渲染器进行渲染时,drf将使用 JSON 渲染器来渲染所有 API 响应,而不会使用任何模板来生成 HTML 页面。因此,在浏览器上就不会显示页面,而是直接显示 JSON 格式的数据。
【2.2.3】局部使用
- 当我们想要指定某个视图的响应只使用
JsonRender
渲染
from rest_framework.renderers import JSONRenderer
class TaskView(APIView):
# 只使用JsonRender渲染响应数据
renderer_classes = [JSONRenderer]
def get(self, request):
ser = TaskSer(Task.objects.all(), many=True)
return Response(ser.data)
【2.2.4】全局使用
# settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
]
}
【2.3】响应状态码
- 为了方便设置状态码,REST framewrok在
rest_framework.status
模块中提供了常用状态码常量。
【2.3.1】信息告知 - 1xx
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
【2.3.2】成功 - 2xx
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS
【2.3.3】重定向 - 3xx
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
【2.3.4】客户端错误 - 4xx
HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
【2.3.5】服务器错误 - 5xx
HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED