django rest framework 入门2——Request and Response

从本节我们开始真正接触rest framework的核心部分。首先我们学习一下一些必备知识。

 

1. Request Object  ——Request对象

rest framework 引入了一个继承自HttpRequest的Request对象,该对象提供了对请求的更灵活解析。request对象的核心部分是request.data属性,类似于request.post, 但在使用WEB API时,request.data更有效。

 

request.POST  # Only handles form data.  Only works for 'POST' method.
request.DATA  # Handles arbitrary data.  Works any HTTP request with content.

2. Response Object ——Response对象

 

rest framework引入了一个Response 对象,它继承自TemplateResponse对象。它获得未渲染的内容并通过内容协商content negotiation 来决定正确的content type返回给client。

 

returnResponse(data)# Renders to content type as requested by the client.

3. Status Codes

 

在views当中使用数字化的HTTP状态码,会使你的代码不宜阅读,且不容易发现代码中的错误。rest framework为每个状态码提供了更明确的标识。例如HTTP_400_BAD_REQUEST。相比于使用数字,在整个views中使用这类标识符将更好。

 

4. 封装API views

在编写API views时,REST Framework提供了两种wrappers:

1).  @api_viwe 装饰器 ——函数级别

2). APIView 类——类级别

这两种封装器提供了许多功能,例如,确保在view当中能够接收到Request实例;往Response中增加内容以便内容协商content negotiation 机制能够执行。

封装器也提供一些行为,例如在适当的时候返回405 Methord Not Allowed响应;在访问多类型的输入request.DATA时,处理任何的ParseError异常。

 

5. 汇总

我们开始用这些新的组件来写一些views。

我们不在需要JESONResponse 类(在前一篇中创建),将它删除。删除后我们开始稍微重构下我们的view

 

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response importResponsefrom snippets.models importSnippetfrom snippets.serializers importSnippetSerializer@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)returnResponse(serializer.data)elif request.method =='POST':
        serializer =SnippetSerializer(data=request.DATA)if serializer.is_valid():
            serializer.save()returnResponse(serializer.data, status=status.HTTP_201_CREATED)else:returnResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

上面的代码是对我们之前代码的改进。看上去更简洁,也更类似于django的forms api形式。我们也采用了状态码,使返回值更加明确。

 

下面是对单个snippet操作的view更新:

 

@api_view(['GET','PUT','DELETE'])def snippet_detail(request, pk):"""
    Retrieve, update or delete a snippet instance.
    """try:
        snippet =Snippet.objects.get(pk=pk)exceptSnippet.DoesNotExist:returnResponse(status=status.HTTP_404_NOT_FOUND)if request.method =='GET':
        serializer =SnippetSerializer(snippet)returnResponse(serializer.data)elif request.method =='PUT':
        serializer =SnippetSerializer(snippet, data=request.DATA)if serializer.is_valid():
            serializer.save()returnResponse(serializer.data)else:returnResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)elif request.method =='DELETE':
        snippet.delete()returnResponse(status=status.HTTP_204_NO_CONTENT)

注意,我们并没有明确的要求requests或者responses给出content type。request.DATA可以处理输入的json请求,也可以输入yaml和其他格式。类似的在response返回数据时,REST Framework返回正确的content type给client。

 

 

6. 给URLs增加可选的格式后缀

利用在response时不需要指定content type这一事实,我们在API端增加格式的后缀。使用格式后缀,可以明确的指出使用某种格式,意味着我们的API可以处理类似http://example.com/api/items/4.json.的URL。

增加format参数在views中,如:

 

def snippet_list(request, format=None):

 

and

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

现在稍微改动urls.py文件,在现有的URLs中添加一个格式后缀pattterns (format_suffix_patterns):

 

from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = patterns('snippets.views',
    url(r'^snippets/$','snippet_list'),
    url(r'^snippets/(?P<pk>[0-9]+)$','snippet_detail'),)

urlpatterns = format_suffix_patterns(urlpatterns)

这些额外的url patterns并不是必须的。

 

来源:

http://blog.csdn.net/zhaoyingm/article/details/8532808

posted @ 2013-12-21 12:42  popoy  阅读(205)  评论(0)    收藏  举报