请求
对于DRF的request对象,有下面的属性:
- .data
- .query_params
- .parsers
- .accepted_renderer
- .accepted_media_type
- .user
- .auth
- .authenticators
- .method
- .content_type
- .stream
REST framework的 Request 类扩展了Django标准的 HttpRequest ,添加了对REST framework请求解析和身份验证的支持。
源代码
class Request(object): """ Wrapper allowing to enhance a standard `HttpRequest` instance. Kwargs: - request(HttpRequest). The original request instance. - parsers_classes(list/tuple). The parsers to use for parsing the request content. - authentication_classes(list/tuple). The authentications used to try authenticating the request's user. """ def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None):
assert isinstance(request, HttpRequest), ( 'The `request` argument must be an instance of ' '`django.http.HttpRequest`, not `{}.{}`.' .format(request.__class__.__module__, request.__class__.__name__) ) self._request = request self.parsers = parsers or () self.authenticators = authenticators or () self.negotiator = negotiator or self._default_negotiator() self.parser_context = parser_context self._data = Empty self._files = Empty self._full_data = Empty self._content_type = Empty self._stream = Empty
REST framework的request请求对象以通常处理表单数据相同的方式使用JSON数据或其他媒体类型处理请求。下面的属性是request中数据主体的部分。
.data
request.data 返回请求正文的解析内容,这与标准的 request.POST 和 request.FILES 属性类似,除了下面的区别:
- request.data 包含所有解析的内容, 包括 文件或非文件输入。
- request.data 支持除 POST 之外的HTTP方法,这意味着你可以访问 PUT 和 PATCH 请求的内容。
- request.data 支持更灵活的请求解析,而不仅仅是表单数据。 例如,你可以与处理表单数据相同的方式处理传入的JSON数据。
@property def data(self): if not _hasattr(self, '_full_data'): self._load_data_and_files() return self._full_data
.query_params
request.query_params 是 request.GET 的一个更准确的同义词,也就是在DRF中的替代品。
为了让你的代码清晰明了, 我们建议使用 request.query_params 而不是Django标准的request.GET 。这样做有助于保持代码库更加正确和明了。通俗地说,就是不要把DRF的属性/方法名和Django原生的属性/方法名混用。
def query_params(self): """ More semantically correct name for request.GET. """ return self._request.GET
.parsers
APIView 类或 @api_view 装饰器将根据view中设置的 parser_classes 值或DEFAULT_PARSER_CLASSES 配置参数进行设置,确保此属性自动设置为 Parser 实例列表。通常并不需要访问这个属性。
Note: 如果客户端发送格式错误的内容,则访问 request.data 可能会引发 ParseError 。默认情况下REST framework的 APIView 类或 @api_view 装饰器将捕获错误并返回 400 BadRequest 响应。
如果客户端发送具有无法解析的内容类型(content-type)的请求,则会引发 UnsupportedMediaType 异常, 默认情况下会捕获该异常并返回 415 Unsupported Media Type 响应。
.user
request.user 默认情况下使用的是Django自带的auth框架的用户模型,返回一个 django.contrib.auth.models.User 实例。但该行为取决于你所使用的的认证策略,很显然当你使用第三方认证模块时,就不一样了。
如果请求未认证则 request.user 的默认值为 django.contrib.auth.models.AnonymousUser 的一个实例。
.method
request.method 返回请求的HTTP方法的 大写 字符串表示形式。隐含支持基于浏览器的 PUT , PATCH 和 DELETE 方法。
.content_type
request.content_type 返回HTTP请求正文的媒体类型的字符串对象,如果未提供媒体类型,则返回空字符串。也就是正文的格式。
一般我们不使用这个属性,但如果真要在DRF中访问请求的内容类型,请务必使用 .content_type 属性,而不是使用 request.META.get('HTTP_CONTENT_TYPE') , 因为前者为基于浏览器的非表单内容提供了隐含的支持。
响应
REST framework 提供一个 Response 类来支持 HTTP内容协商,该类允许返回可以呈现为多种类型的内容,具体取决于客户端的请求。
这个 Response 类是 Django中 SimpleTemplateResponse 类的一个子类。 Response 对象使用Python原生的数据类型进行初始化。 然后REST framework 使用标准的HTTP内容协商来确定如何呈现最终的响应内容。
我们并不一定非要使用DRF的 Response 类进行响应,也可以返回常规的 HttpResponse 或者 StreamingHttpResponse 对象,但是使用 Response 类可以提供一个多种格式的更漂亮的界面。
除非由于某种原因你要对 REST framework 做大量的自定义,否则你应该始终使用 APIView 类或者 @api_view 函数这些DRF提供的视图。这样做可以确保视图在返回之前能够执行 内容协商并且为响应选择适当的渲染器。
Django中的模型中的具体数据内容可以json化,我们需要自己写serializer,也就是序列化器,进行模型model对象的序列化和反序列化。如果不这么做,那前端看着后端发来的数据会懵逼的,后端拿着前端post过来的数据也不知道该怎么存到数据库里去。
你可以使用 REST framework的 Serializer 类来执行此类数据的序列化,或者使用你自定义的序列化器。
参数说明:
.data
未渲染的,已经序列化的要响应的数据
.status_code
HTTP 响应的数字状态码。
content_type
响应的内容类型。通常由渲染器自行设置,由协商内容确定,但是在某些情况下,你需要明确指定内容类型。