DRF的Request


DRF API Guide

1. Requests

REST frameworkRequest继承自标准的HttpRequest,增加对REST框架灵活的请求解析和请求认证的支持。

1.1 Request parsing/请求解析

REST frameworkRequest提供了灵活的请求解析,允许你以操作form表单数据的方式处理JSON数据或其它mediatypes

.data

request.data返回request body的解析内容,这类似于标准的request.POSTrequest.FILES

.query_params

request.query_paramsrequest.GET的同义词,不仅可以替换reqesut.GET,为了保持代码的统一性,任何HTTP方法类型都可以包括query parameters,不仅仅是GET request

.parsers

APIView@api_view装饰器确保request.parsers自动设置为Parser实例的列表,基于view上的parser_classesDEFAULT_PARSER_CLASSES设置。

通常不需要访问这个属性。

假如client发送了格式错误的内容,这时访问request.data可能抛出ParseError。默认REST frameworkAPIView类或@api_view装饰器将捕获这个error,并返回404_Bad_Request的响应类型。

假如client发送了一个不支持的content-type类型,这时UnsupportedMediaType异常将被抛出,默认将被捕获,并返回415_Unsupported_Media_type的响应类型。

1.2 Content negotiation/内容协商

request暴露以下属性,允许你自行决定协商阶段的结果,你可以为不同的media type选择不同的序列化方案。

.accepted_renderer

内容协商阶段选择的内容renderer实例。

.accepted_media_type

内容协商阶段选择的内容media type字符串。

1.3 Authentication/认证

REST framework提供了灵活的、基于每个request的认证,提供:

  • 对于不同的API使用不同的认证策略。
  • 支持使用多个认证策略。
  • 为传入的reqesut提供usertoken相关信息。

.user

request.user,典型的是django.contrib.auth.models.User的实例,依赖于所使用的认证策略。

.auth

request.auth返回任何附加的认证上下文。依赖于不同的认证策略扩展了request.auth。典型的实例是一个token

假如request没有认证或者没有提供上下文,则request.auth默认是None

.authenticators

APIView@api_view装饰器确保request.authenticators自动设置为Authentication实例的列表,基于view上的authentication_classesDEFAULT_AUTHENTICATORS_CLASSES设置。

通常不需要访问这个属性

当调用.user.auth属性时可能会抛出WrappedAttibuteError,这个错误源于认证的AttributeError,抛出时重新封装了不同的异常类型,防止外部访问受限,Python不会识别这个错误是来源于认证器的,而是假设request没有.user.auth

1.4 Browser enhancements/浏览增强

REST framework支持一些浏览器增强功能,例如PUT,PATCHDELETE

.method

request.method返回请求方法的小写字符串。同时支持PUT,PATCHDELETE

.content_type

request.content_type返回HTTP请求体的media类型字符串对象,未提供则返回空串。

通常不需要访问这个属性,默认Django会处理。

如果您确实需要访问请求的内容类型,您应该优先使用.content_type属性而不是使用request.META.get('HTTP_CONTENT_TYPE'),因为它为基于浏览器的非表单内容提供了透明支持。

.stream

request.stream 返回一个流,代表请求体的内容。

通常不需要访问这个属性,默认Django会处理。

1.5 Standard HttpRequest attributes/标准的HttpRequest属性

作为扩展了DjangoHttpRequestRESTRequest,所有其他的属性和方法都有效,比如request.METArequest.session的字典。

请注意,由于实现原因,Request类并不继承自HttpRequest类,而是使用组合来扩展该类。

理解

DRFRequest类型是对Django HttpRequest的增强,提供了更加统一的request使用方法,包括解析和认证:

  • [ ] 解析用的多的是.data.query_params,分别获取请求体参数和URL查询参数,提供了统一的参数获取方式。
  • [ ] 认证用的多的是.user.auth,分别提供了不同认证策略下的认证相关信息,.user是DjangoUser,典型的基于Token的认证策略下.user是已认证用户,.auth是已认证的token

DRFRequest的内部实现不是继承于DjangoHttpRequest,而是用一种混入方式扩展了该类,源码中request._request即为DjangoHttpRequest


2. Responses

DRFResponse类是Django SimpleTemplateResponse的子类,提供了对client请求内容的统一呈现方式,可以渲染多个content types,通常不需要使用该类,而应该使用HttpResponseStreamHttpResponse,除非必要,应该总是在APIView@api_view中返回Response

2.1 Creating response/创建

Response()

签名:Response(data, status=None, template_name=None, headers=None, content_type=None)

与常规HttpResponse对象不同,您不需要用渲染后的内容实例化Response对象。可以直接传入需要渲染的数据,使用原生的Python类型。

Response类使用的渲染器无法处理复杂数据类型,如DjangoModel实例,在创建Response之前,需要使用DRFSerializer类将数据进行序列化,也可以自定义Serializer

  • data: 序列化的数据.
  • status:response的状态码,默认是200。
  • template_name: 假如使用 HTMLRenderer,则这里代表模板名字。
  • headers: HTTP headers字典。
  • content_type: 自动通过内容协商进行设置,因此你不需要指定该值。

Attributes

.data

未序列化的数据。

.status_code

HTTP响应状态码

.content

渲染内容,.render()方法被调用方可访问.content

.template_name

仅在使用了HTMLRenderer及其它定制的渲染器,template_name才提供。

.accepted_renderer

用于渲染内容的渲染器实例。在APIView@api_view中自动被设置。

.accepted_media_type

内容协商阶段的media type.在APIView@api_view中自动被设置。

2.2 Standard HttpResponse attributes

Response类继承自SimpleTemplateResponse,常用的属性和方法均可使用,例如你可以使用标准方法设置header

response = Response()
response['Cache-Control'] = 'no-cache'

.render()

签名:.render()

与其他的TemplateResponse一样,这个方法被调用用于渲染序列化数据到最终的response的内容。

通常不需要访问这个属性,默认Django会处理。


理解

Response继承自SimpleTemplateResponse,提供了对APIView@api_view的响应内容,通常我们使用HttpResponseStreamHttpResponse,同时也不需要关注content-type等属性的管理,仅需要关注data的序列化,以呈现内容。