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。
-
@api_view
装饰器适用于function based views -
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,但是它给我们一个简单,干净的特定格式。