官网地址

Request 和 Response

这一章将开始覆盖Rest framework的核心。让我们来介绍一些基础组件。

Restquest object

Rest framework 引入了一个继承于django HttpRequest的对象Request,并提供更灵活的解析。
Request的核心是request.data属性,他类似于request.POST,但对web api更有用。

request.POST #只处理form data,而且只适用于'POST'方法
request.data #处理所有数据,适用于 'POST','PUT','PATCH'

Response Object

Rest framework 也引入了Response对象,它是一个TemplateResponse类型,并根据客户端需求正确返回需要的类型。

return Response(data) # 根据客户端的需求返回不同的类型。

Status codes

在你的views中使用HTTP状态码,总是不太容易阅读的,而且稍不注意,你会返回一个错误的状态码。Rest framework为每个状态码提供了更为明确的标识符。例如 status模块中的 HTTP_400-BAD_REQUEST

装饰API views

REST framework为你提供了两个装饰器,你能够使用它们来写你的API views。

  1. @api_view装饰器适用于function based views
  2. APIView装饰器适用于 class-based views
    这些方法提供一些功能,例如确保你的view收到的请求类型是Request,并将上下文添加到Response当中,这样就能根据客户端的需要返回。

装饰器还提供行为,例如适当的时候返回405 Method Not Allowed和当访问request.data或者输入错误时,处理所有的'ParseError'异常。

结合之前的内容

好,来开始使用新的组件来写我们的views。
我们再也不需要在views.py中使用JSONResonse了。我们来开始重构我们的views.

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 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)

我们所展示的示例view和之前相比,有了相当大的进展。它更小更简洁,如果我们正在使用Form API,会发现这个代码非常的相似。我们也能够使用 named status codes

接下来,我们将在views.py模块中展示一个snippet的详情。

@api_view(['GET','PUT','DELETE'])
def snippet_detail(request,pk)
'''
检索,更新或者删除一个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.date)
    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.HTPP_400_BAD_REQUEST)
        
    elif request.method == "DELETE":
        snippe.delete()
        return Response(status.status.HTTP_204_NO_CONTENT)

这一切都应该感觉特别熟悉-它和标准的Django views没多少不同。

注意:我们不再明确指定 request和response的响应类型。request.data能够处理所有进来的json请求,但他也能够处理其他的格式。同样,我们在response中返回我们的数据,但是由REST framework 来帮助我们来为不同的请求做出正确的响应内容。

添加url

为我们刚才编写的两个view添加url.

def snippet_list(request,format=None)
def snippet_detail(request,pk,format=None)

现在,我们稍微修改一下我们的urls.py文件。

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 patterns,但是它给我们一个简单,干净的特定格式。


張怼怼
107 声望43 粉丝