请求对象(Request objects)
REST框架引入了一个扩展了常规HttpRequest的Request对象,并提供了更灵活的请求解析。Request对象的核心功能是request.data属性,它与request.POST类似,但对于使用Web API更为有用。
request.POST # 只处理表单数据 只适用于'POST'方法 request.data # 处理任意数据 适用于'POST','PUT'和'PATCH'方法
响应对象(Response objects)
REST框架还引入了一个Response对象,这是一种获取未渲染(unrendered)内容的TemplateResponse类型,并使用内容协商来确定返回给客户端的正确内容类型
return Response(data)  # 渲染成客户端请求的内容类型。
状态码(Status codes)
在你的视图(views)中使用纯数字的HTTP 状态码并不总是那么容易被理解。而且如果错误代码出错,很容易被忽略。REST框架为status模块中的每个状态代码(如HTTP_400_BAD_REQUEST)提供更明确的标识符。使用它们来代替纯数字的HTTP状态码是个很好的主意。
包装(wrapping)API视图
REST框架提供了两个可用于编写API视图的包装器(wrappers)。
- 
用于基于函数视图的 @api_view装饰器。
- 
用于基于类视图的 APIView类。
这些包装器提供了一些功能,例如确保你在视图中接收到Request实例,并将上下文添加到Response,以便可以执行内容协商。
包装器还提供了诸如在适当时候返回405 Method Not Allowed响应,并处理在使用格式错误的输入来访问request.data时发生的任何ParseError异常。
正式开始
好了,我们要创建一个用于创建简单Web API的app。
python manage.py startapp snippets

 我们需要将新建的snippetsapp和rest_frameworkapp添加到INSTALLED_APPS。让我们编辑tutorial/settings.py文件:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'quickstart.apps.QuickstartConfig', 'snippets.apps.SnippetsConfig', 'rest_framework', ]
请注意如果你使用的Django版本低于1.9,你需要使用snippets.apps.SnippetsConfig替换snippets。
创建一个model
组合在一起
好的,我们开始使用这些新的组件来写几个视图。
我们在views.py中不再需要JSONResponse类了,所以把它删除掉。删除之后,我们就可以开始重构我们的视图了。
from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from snippets.models import Snippet from snippets.serializers import SnippetSerializer @api_view(['GET', 'POST']) def snippet_list(request): """ List all code snippets, or create a new snippet. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我们的实例视图是我们之前例子的改良版。简明了很多,并且目前的代码和我们使用Forms API很相似。我们也用有意义的状态码标识符。 在views.py模块中,有一个独立的snippet视图。
@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        snippet = Snippet.objects.get(pk=pk)
    except Snippet.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)
    if request.method == 'GET':
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)
    elif request.method == 'PUT':
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
这对我们来说应该非常熟悉,因为它与常规的Django视图没有什么区别。 注意,我们不再明确打印我们的对指定内容类型的请求或响应。request.data能够处理json请求,但是它也能处理其他格式。相似地,虽然我们可以在响应对象中带数据,但允许REST框架渲染响应成正确的内容类型。
在我们的链接(URLs)后添加可选格式后缀
为了利用我们的响应内容不再是单一格式的事实,我们应该为我们的API尾部添加格式后缀。用格式后缀给我们明确参考指定格式的URL,这意味着我们的API能够处理像http://example.com/api/items/4/.json一样的链接。 在视图函数中添加一个format参数,像这样:
def snippet_list(request, format=None):
和
def snippet_detail(request, pk, format=None):
现在可以很快更新urls.py文件,在已经存在的URL中添加一个格式后缀模式(format_suffix_patterns)。
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = [
    url(r'^snippets/$', views.snippet_list),
    url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
我们不必添加额外的URL模式,但是它给我们简单、清楚的方式渲染除特定的格式。
看看吧
和教程第一部分一样,我们要开始从命令行测试API。虽然我们能在发送无效的请求时更妥当处理错误,但是现在一切都做的够好了。 我们能想之前一样获取所有的snippets列表。
http http://127.0.0.1:8000/snippets/
HTTP/1.1 200 OK
...
[
  {
    "id": 1,
    "title": "",
    "code": "foo = "bar"
",
    "linenos": false,
    "language": "python",
    "style": "friendly"
  },
  {
    "id": 2,
    "title": "",
    "code": "print "hello, world"
",
    "linenos": false,
    "language": "python",
    "style": "friendly"
  }
]
我们能控制我们返回的响应格式,或者使用Accept响应头。
http http://127.0.0.1:8000/snippets/ Accept:application/json # Request JSON http http://127.0.0.1:8000/snippets/ Accept:text/html # Request HTML
或者在URL后添加格式后缀:
http http://127.0.0.1:8000/snippets.json # JSON 后缀 http http://127.0.0.1:8000/snippets.api # 浏览用的 API 后缀
同样地,我们可以控制我们发送的请求格式,用Content-Type请求头。
# POST using form data
http --form POST http://127.0.0.1:8000/snippets/ code="print 123"
{
  "id": 3,
  "title": "",
  "code": "print 123",
  "linenos": false,
  "language": "python",
  "style": "friendly"
}
# POST using JSON
http --json POST http://127.0.0.1:8000/snippets/ code="print 456"
{
    "id": 4,
    "title": "",
    "code": "print 456",
    "linenos": false,
    "language": "python",
    "style": "friendly"
}
你也可以从浏览器打开API,通过访问http://127.0.0.1:8000/snippets/。
Browsability
因为API是基于客户端请求来选择响应内容的类型,所以默认情况下,在Web浏览器访问资源时,API返回HTML格式的资源。这语序API返回完全可以网页浏览的HTML。 有可以网页浏览API是很好的,这使开发和使用你的API更简单,这也为其他想要查看和使用你的API的开发者大大降低了门槛。 关于可浏览API的特性和如何自定义可浏览API,请见可浏览API话题。
接下来要干什么?
我们基于视图用类,并且看看普通的视图我们如何减少代码。
扫码关注微信公众号 “小樊Study”获取更多
 
 
直男们,扫我送女友哟!

