欢迎访问我的个人网站:www.comingnext.cn
前言
在上一篇文章中,主要讲的是请求和响应,项目里面views.py中的视图函数都是基于函数的,并且我们介绍了@api_view这个很有用的装饰器。同时,我们还介绍了APIView这个类,但是还没使用它。在这篇文章中,我们要做的是把基于方法的视图改为基于类的视图,将会了解到APIView。
改为基于类的视图
重构一下snippets/view.py:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
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, format=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请求分离开变成单个的方法,而不是if...elif...这样的结构,所以这样处理起来很更加的高效。
同样的,把另一个视图函数也进行修改:
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)
改为基于类的视图之后,当然也要修改一下路由了,对snippets/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<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
这样就可以运行程序了,功能和之前的是一样的
使用mixins类
使用基于类的视图的好处除了上面所说的把各种HTTP请求分离开,还有什么好处吗?答案是肯定的——使用基于类的视图的最大优势之一是它可以轻松地构成可重复使用的行为。
可重复使用的行为?简单说,就是让我们少写一点功能类似的代码,由此就要介绍一下mixins类了,它帮我们封装了很多操作,简化代码,使用也很简单,编辑snippets/view.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 = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
新的视图类中继承了 generic.GenericAPIView、mixins.ListModelMixin和mixins.CreatteModelMixin,类的作用看字面意思就能懂啦,mixins类为我们提供了list()和create()方法,当然,使用这两个函数需要先设置queryset和serializer_class,这点我们查看一