Django REST framework API Guide 之 Requests

最近用DRF写接口,发现自己面对一些复杂需求的时候,还是很不顺手。有必要对DRF 一些基本的概念和方法进行梳理。故有Django REST framework API Guide 系列博客。

概览

在官网上,DRF 的 API Guide 涉及如下模块:

  • Requests 请求
  • Response 响应
  • Views 视图
  • Generic views 通用视图
  • Viewsets 视图集合类
  • Routers 路由器
  • Parsers 解释器
  • Renderers 渲染器
  • Serializers 序列化器
  • Serializer fields 序列化器字段
  • Serializer relations 序列化器之间的关系
  • Validators 验证器
  • Authentication 认证
  • Permissions 权限
  • Caching 缓存
  • throttling 限流
  • Filtering 过滤
  • Pagination 分页
  • Versioning 版本
  • Content negotiation 内容协商
  • Metadata 元数据
  • Schemas 架构
  • Format suffixes 格式后缀
  • Returning URLS 返回url
  • Exceptions 异常
  • Status codes 状态码
  • Testing 测试
  • Settings 设置

Requests

If you’re doing REST-based web service stuff … you should ignore request.POST.
如果你在做有关基于Restful 的 web 服务的活儿时,你应该忽略掉 request.POST
– Malcom Tredinnick, Django developers group

REST framework 的Request 类拓展了标准的 HttpRequest,针对 REST framework 灵活的 request 解析和认证增加了相应的支持。

Request 解析

REST framework 的 Request 对象提供了灵活的请求解析,可以允许你如同处理表单数据那样处理请求中的 JSON data 或者其他媒体类型的数据。

.data

request.data 返回 request body 解析后的内容。和 django 标准的 request.POST 以及 request.FILES 类似,除了如下:

  • .data 包含了所有解析后的内容,包括 file 和 non-file 输入
  • 不仅仅支持解析 POST,也支持解析其他 http 方法的内容,意味着你可以获得 PUT 和 PATCH 请求的内容
  • 除了支持解析表单数据,也支持 REST framework 的其他灵活的请求解析。比如你可以类似处理表单数据那样处理 JSON 数据

更多细节,可以参看解析器的文档

.query_params

request.query_params 与 request.GET 是同义词,不过命名更准确。
为了使你的代码更加明晰,我们推荐使用 request.query_params 而不是django 标准的 request.GET。这样做可以有助于让你的代码更加准确和显而易见。任何http 方法都可能包含查询参数,不仅仅是 GET 请求。

.parsers

APIView 类和 @api_view 装饰器会确保这个属性值会自动设置为一个基于view 中的 parser_classes 或者 setting 中的 DEFAUT_PARSER_CLASSES 的解释器实例列表。

一般而言,你不需要获取这个属性值。

注意:

  • 当客户端发送内容包含格式错误,当去获取 request.data 时,可能触发 ParseError。默认情况下,APIView 和 @api_view 装饰器会捕捉这个错误并返回 404 Bad Request。

  • 如果客户端发送一个不能被解析的内容格式,UnsupportedMediaType 会被触发,默认情况下会被捕捉并返回 415 Unsupported Media Type

内容协商 content negotiation

request 会暴露一些属性,可以允许你自行定义返回内容的形式。这允许你去有些自主行为,比如针对不同的媒体形式去选择不同的序列化器

.accepted_renderer

被内容协商选中的渲染器实例。

.accepted_media_type

一个表示基于内容协商能够接受的媒体类型的字符串。

Authentication

REST framework 提供灵活的,这对每个请求的认证,这让你能够做如下事情:

  • 针对不同部分的api 提供不同的认证策略
  • 支持多种认证策略
  • 结合到来的请求,同时提供用户和token信息

.user

request.user 通常返回一个 django.contrib.auth.models.User 的实例,尽管他的行为取决于所应用的认证策略。
如果request请求未被认证,request.user 默认值为 django.contrib.auth.models.AnonymousUser 的实例。
更多细节,参看 authentication documentation(https://www.django-rest-framework.org/api-guide/authentication/)。

.auth

request.auth 返回任何额外的认证信息。request.auth的实际行为取决于所应用的认证策略。不过一般而言,回事一个 token 实例。
如果请求没有被认证,或者没有额外多余的内容,request.auth 的默认值是 None。
更多细节,参看 authentication documentation (https://www.django-rest-framework.org/api-guide/authentication/)

.authenticators

APIView 类或者@api_view装饰器会确保这个属性会自动设置成为一个由 Authentication 实例组成的列表,这些实例基于view中的authentication_classes或者DEFAULT_AUTHENTICATORS。
你一般不需要去获取这个属性值。

浏览器增强 Browser enhancements

REST framework 支持一些浏览器增强,比如基于浏览器的PUT, PATCH 和 DELETE 形式。

.method

request.method 返回 requet 的 HTTP 方法的大写字符串
更多细节,参看浏览器增强(https://www.django-rest-framework.org/topics/browser-enhancements/)

.content_type

request.content_type 返回一个字符串对象,表示HTTP request body中的媒体类型,或者当没有提供媒体类型时,会是一个空字符串。
通常情况下,由于你已经依赖了REST framework的默认request 解析行为,所以你不需要或者这个属性值。
更多细节,参看浏览器增强(https://www.django-rest-framework.org/topics/browser-enhancements/)

.stream

request.stream 返回 request body 内容的stream表示。
通常情况下,由于你已经依赖了REST framework的默认request 解析行为,所以你不需要或者这个属性值。

Standard HttpRequest attributes

REST framework 的 Request 是对 Django HttpRequest 的扩展,所以其他标准的属性和方法在 Request 中也是可用的。比如 request.META 和 request.session。