让我们看看通过 Serializer 类怎样来编写 API 的视图函数,现在我们不会使用 REST 框架中的特性,仅仅写原生的Django视图函数。

一.我们创建一个 HttpResponse 的子类,用来将任何数据转换成 JSON格式.

编辑snippets/views.py,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from  django.http  import  HttpResponse
from  django.views.decorators.csrf  import  csrf_exempt
from  rest_framework.renderers  import  JSONRenderer
from  rest_framework.parsers  import  JSONParser
from  snippets.models  import  Snippet
from  snippets.serializers  import  SnippetSerializer
class  JSONResponse(HttpResponse):
     """
     An HttpResponse that renders its content into JSON.
     """
     def  __init__( self , data, * * kwargs):
             content  = JSONRenderer().render(data)
             kwargs[ 'content_type' ] = 'application/json'
             super (JSONResponse,  self ).__init__(content, * * kwargs)

二.我们API的目的是,可以通过view来列举全部的Snippet的内容,或者创建一个新的snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@csrf_exempt
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  JSONResponse(serializer.data)
     elif  request.method  = = 'POST' :
       data  = JSONParser().parse(request)
        serializer  = SnippetSerializer(data = data)
        if  serializer.is_valid():
            serializer.save()
            return  JSONResponse(serializer.data, status = 201 )
        return  JSONResponse(serializer.errors, status = 400 )

注意,因为我们要通过client向该view post一个请求,所以我们要将该view 标注为csrf_exempt, 以说明不是一个CSRF事件。它不同于以往的正常的视图函数,REST框架的视图函数事实上使用更加敏感的行为,它现在只是为了达到我们的目的。

三.我们还要一个视图函数来为单独的 snipet 实例服务,用来恢复,更新和删除 snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@csrf_exempt
def  snippet_detail(request, pk):
    """
       Retrieve, update or delete a code snippet.
       """
   try :
        snippet  = Snippet.objects.get(pk = pk)
   except  Snippet.DoesNotExist:
     return  HttpResponse(status = 404 )
   if  request.method  = = 'GET' :
        serializer  =  SnippetSerializer(snippet)  
       return  JSONResponse(serializer.data)
     elif  request.method  = = 'PUT' :
         data  = JSONParser().parse(request)
         serializer  = SnippetSerializer(snippet, data = data)
         if  serializer.is_valid():                
              serializer.save()
              return  JSONResponse(serializer.data)
         return   JSONResponse(serializer.errors, status = 400 )
     elif  request.method  = = 'DELETE' :
         snippet.delete()
         return  HttpResponse(status = 204 )

四.将views.py保存,在Snippets目录下面创建urls.py,添加以下内容:

1
2
3
4
5
6
from  django.conf.urls  import  patterns, url
 
urlpatterns  =  patterns( 'snippets.views' ,
     url(r '^snippets/$' , 'snippet_list' ),
     url(r '^snippets/(?P<pk>[0-9]+)/$' , 'snippet_detail' ),
)

四.测试

1
python manage.py runserver

在另外的终端中:

1
2
3
curl http: / / 127.0 . 0.1 : 8000 / snippets / [{ "id" 1 "title" : " ", " code ": " foo  =  \ "bar\"\n" "linenos" : false,  "language" "python" "style" :
     "friendly" }, { "id" 2 "title" : " ", " code ": " print  \ "hello, world\"\n" "linenos" : false,  "language" :
     "python" "style" "friendly" }]