从此刻开始,我们才真正涉及 REST framework 的核心部分。让我们介绍几个极其重要的结构组件(building blocks)。
请求对象 Request
引入一个 Request
对象扩展了常规的 HttpRequest
,提供更灵活的请求解析。Request
对象的核心功能是 request.data
属性,跟 request.POST
有点像,但是对于操作 Web API 来说更有用。
1 | request.POST # 仅处理表单数据。仅对 'POST' 方法有效。 |
响应对象 Response
REST framework 也提供了一个 Response
对象。它是 TemplateResponse
类型,接收为渲染的内容,通过使用内容协议来确定正确的内容类型(content type)返回给客户端。
1 | return Response(data) # 渲染为客户端请求的内容类型。 |
状态码
在视图中使用数字化的状态码未必总会被明显阅读到,而且即便你得到一个错误的状态码也很容易忽视。REST framework 在 status
模块中给每个状态码都提供了更加明确的标识符,比如 HTTP_400_BAD_REQUEST
。始终使用这些而不是数字标识符无疑是明智之举。
API 视图封装 wrapper
REST framework 提供两个用于编写 API 视图的封装。
@api_view
装饰器用于处理函数视图(function based views)。APIView
类用于处理类视图(class-based views)。
这些封装器(wrapper)提供了几个功能,比如确保在你在视图中接收到 Request
实例对象,并且给 Response
对象增加语句,从而内容协议能够被执行。
封装器也提供了一些行为,比如在恰当的时候返回 405 Method Not Allowed
响应,也会处理任何在获取到异常输入的 request.data
时引发的 ParseError
解析异常。
把它们全都拼凑起来
好了,让我们继续,开始用这些新组件稍微重构一下我们的视图(views)。
1 | from rest_framework import status |
我们的实例视图是对之前视图的一个优化。它更加简明一点,而且现在的代码同我们过去操作的 Forms API 非常相似了。我们也在使用名称化的状态码,这使得响应的含义更加显而易见。
这里是针对一个单独的代码段的视图,在 views.py
模块中。
1 |
|
这应该都很熟悉了——这跟常规的 Django 视图没什么不同。
注意我们不再将我们的请求和响应与得到的内容类型明确绑定。request.data
不但可以处理获得的 json
请求,也能够处理其他格式。类似地,我们返回带着数据的响应对象,而让 REST framework 帮我们把响应渲染成正选的内容类型。
给我们的 URL 添加可选的格式后缀
针对我们的响应不再硬性关联到单个内容类型这一情况,让我们为 API 端点添加对格式后缀的支持。使用格式后缀给我们明确指明格式的 URL,这意味着我们的 API 将能够处理 http://example.com/api/items/4.json 这样的 URL。
让我们以给两个视图都加上一个 format
关键字参数开始,就像这样。
1 | def snippet_list(request, format=None): |
和
1 | def snippet_detail(request, pk, format=None): |
现在,稍微更新一下 snippets/urls.py
文件,在已经存在的 URL 后面追加一系列的 format_suffix_patterns
。
1 | from django.urls import path |
我们不必加入这些额外的 url 模式,不过这给我们提供一个简单整洁的方式查看一个特定的格式。
它看起来如何?
继续,从命令行测试 API,就像我们在 教程第 1 部分 做的那样。一切都似曾相识,不过如果发送无效的请求,我们已经能够得到一些更好的错误处理。
我们可以得到所有代码段的列表,就像之前那样。
1 | http http://127.0.0.1:8000/snippets/ |
我们既可以通过使用请求头的方式控制我们想要拿回的响应格式:
1 | http http://127.0.0.1:8000/snippets/ Accept:application/json # 请求 JSON |
也可以通过末尾加上格式后缀:
1 | http http://127.0.0.1:8000/snippets.json # JSON 后缀 |
类似地,通过使用 Content-Type
请求头,我们可以控制我们发送求情的格式。
1 | # POST 方法发送表单数据 |
如果你在上面的 http
请求中加上一个 --debug
开关,你将能在请求头中看到请求类型。
现在去浏览器中打开 API,访问 http://127.0.0.1:8000/snippets/。
可浏览器访问性
因为 API 是基于客户端的请求来选择响应的内容类型,所以当浏览器访问资源时,它将默认返回一个 HTML 格式的资源语句。这允许 API 返回一个完全可浏览器访问的 HTML 语句。
得到一个可浏览器访问的 API 是一个巨大的可用性胜利,这使得开发和使用你的 API 更加容易。这也极大地降低了其他开发者研究和使用你的 API 的门槛。
参见 可浏览器访问的 api 话题获取更多关于可浏览器访问的 API 特性和如何定制它的信息。
接下来做什么?
在 教程的第 3 部分,我们将会开始使用类视图(class-based views),并且管窥通用视图是如何减少我们要写的代码量的。