django-rest-framework指南(3):Class Based Views(类视图)

Tutorial 3: Class Based Views

我们也能使用类视图代替函数视图来写API视图.这是一个强大的功能,能够重用代码,是代码DRY(don’t repeat yourself).

Rewriting our API using class based views(使用视图类重写API)

我们开始将根视图重写为类视图.只需要稍微重构下views.py就行了.

from snippets.models import Snippet
from snippets.serializers import SnippetSerailizer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class SnippetList(APIView):
    '''
    列出所有snippet,或者创建一个新的snippet
    '''
    def get(self, request, fromat=None):
        snippets = Snippet.objects.all()     
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        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)

目前为止,一切顺利.看起来和上一个例子很相似,但是我们很好的分隔了不同的HTTP方法.We’ll also need to update the instance view in views.py.

class SnippetDetail(APIView):
    '''
    查询,更新或删除一个snippet实例
    '''
    def get_object(self, pk):
        try:
            return Snippet.objects.get(pk=pk)    
        except Snippet.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        snippet = self.get_object(pk)
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

看起来不错.还是和视图函数很像.我们还要重构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.SnippetList.as_view()),
    url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view())
]

urlpatterns = format_suffix_patterns(urlpatterns)

ok,完成.如果你运行开发服务器,一切都和之前一样工作.

Using mixins(使用混合模式)

使用视图类的一个好处是我们可以很容易的复用代码.
我们使用的CRUD方法和我们写的model-backed API视图很像.这些共同的行为(behaviour)在REST framework的混合类(mixin class)中有实现.
接下来让我们看看怎么使用混合类来写视图.这是我们的views.py.

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import mixins
from rest_framework import generics

class SnippetList(mixins.ListModelMixin,
                mixins.CreateModelMixin,
                generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerialier

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

让我们花点时间看看到底发生了什么.我们使用GenericAPIView来构建视图,还加入了CreateModelMixin和ListModelMixin.
基类提供了核心功能,mixin类提供了.list()和.create()操作.然后我们显式的将get和post方法绑定了合适的操作.到此为止,都很简单.

class SnippetDetail(mixins.RetrieveModelMixin,
                mixin.UpdateModelMixin,
                mixin.DestoryModelMixin,
                generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destory(request, *args, **kwargs)

非常相似.我们使用GenericAPIView类来提供核心功能,使用mixins来提供.retrieve(), .update(),和.destory()操作.

Using generic class based views

使用mixins我们能用更少的代码重写视图,但是我们可以更进一步.REST framework提供了一组已经mixed-in generic的视图,能用更少的代码来写views.py

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics


class SnippetList(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

class SnippetDetail(generics.RetrieveUpdateDestoryAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

WOW,这真简洁.我们可以省很多时间,而且我们的代码看起来像良好,干净的,通顺的Django.
接下来的指南(4),我们将会看一下怎么为我们的API做权限和验证.

你可能感兴趣的:(django)