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

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

编辑snippets/views.py,如下:

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

@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

@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,添加以下内容:

from django.conf.urls import patterns, url

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

四.测试

python manage.py runserver

在另外的终端中:

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"}]