python rest api和视图函数区别_Django编写RESTful API(三):基于类的视图

前言

在上一篇文章中,主要讲的是请求和响应,项目里面views.py中的视图函数都是基于函数的,并且我们介绍了@api_view这个很有用的装饰器。同时,我们还介绍了APIView这个类,但是还没使用它。在这篇文章中,我们要做的是把基于方法的视图改为基于类的视图,将会了解到APIView。

改为基于类的视图

重构一下snippets/view.py:

from snippets.models importSnippetfrom snippets.serializers importSnippetSerializerfrom django.http importHttp404from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework importstatusclassSnippetList(APIView):"""列出所有已经存在的snippet或者创建一个新的snippet"""

def get(self, request, format=None):

snippets=Snippet.objects.all()

serializer= SnippetSerializer(snippets, many=True)returnResponse(serializer.data)def post(self, request, format=None):

serializer= SnippetSerializer(data=request.data)ifserializer.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...这样的结构,所以这样处理起来很更加的高效。

同样的,把另一个视图函数也进行修改:

classSnippetDetail(APIView):"""检索查看、更新或者删除一个snippet"""

defget_object(self, pk):try:return Snippet.objects.get(pk=pk)exceptSnippet.DoesNotExist:raiseHttp404def get(self, request, pk, format=None):

snippet=self.get_object(pk)

serializer=SnippetSerializer(snippet)returnResponse(serializer.data)def put(self, request, pk, format=None):

snippet=self.get_object(pk)

serializer= SnippetSerializer(snippet, data=request.data)ifserializer.is_valid():

serializer.save()returnResponse(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 importurlfrom rest_framework.urlpatterns importformat_suffix_patternsfrom snippets importviews

urlpatterns=[

url(r'^snippets/$', views.SnippetList.as_view()),

url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view()),

]

urlpatterns= format_suffix_patterns(urlpatterns)

这样就可以运行程序了,功能和之前的是一样的

使用mixins类

使用基于类的视图的好处除了上面所说的把各种HTTP请求分离开,还有什么好处吗?答案是肯定的——使用基于类的视图的最大优势之一是它可以轻松地构成可重复使用的行为。

可重复使用的行为?简单说,就是让我们少写一点功能类似的代码,由此就要介绍一下mixins类了,它帮我们封装了很多操作,简化代码,使用也很简单,编辑snippets/view.py函数:

from snippets.models importSnippetfrom snippets.serializers importSnippetSerializerfrom rest_framework importmixinsfrom rest_framework importgenericsclassSnippetList(mixins.ListModelMixin,

mixins.CreateModelMixin,

generics.GenericAPIView):

queryset=Snippet.objects.all()

serializer_class=SnippetSerializerdef 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,这点我们查看一下mixins的源码就可以看出来了,比如list方法:

classListModelMixin(object):"""List a queryset."""

def list(self, request, *args, **kwargs):

queryset=self.filter_queryset(self.get_queryset())

page=self.paginate_queryset(queryset)if page is notNone:

serializer= self.get_serializer(page, many=True)returnself.get_paginated_response(serializer.data)

serializer= self.get_serializer(queryset, many=True)return Response(serializer.data)

这里的代码会分别通过get_queryset()和get_serializer()得到查询集和序列化器,其他封装好的方法也是如此。

知道了这个,再修改一下另一个视图类就很容易了:

classSnippetDetail(mixins.RetrieveModelMixin,

mixins.UpdateModelMixin,

mixins.DestroyModelMixin,

generics.GenericAPIView):

queryset=Snippet.objects.all()

serializer_class=SnippetSerializerdef 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.destroy(request, *args, **kwargs)

使用通用的视图类

到这里,视图代码已经简化了许多了,但是我要告诉你的是,还可以进一步简化。。。在此,让我们一起在心中默念:

人生苦短,我用Python

进一步简化就是连mixins类都不用了,只使用generics就可以了,代码如下:

from snippets.models importSnippetfrom snippets.serializers importSnippetSerializerfrom rest_framework importgenericsclassSnippetList(generics.ListCreateAPIView):

queryset=Snippet.objects.all()

serializer_class=SnippetSerializerclassSnippetDetail(generics.RetrieveUpdateDestroyAPIView):

queryset=Snippet.objects.all()

serializer_class= SnippetSerializer

好了,现在的代码就显得非常简洁了,但是短小却精悍,依然可以实现原本的功能,随意的展示一下:

把基于函数的视图改成基于类的视图就讲到这里了,下一篇文章会介绍授权和权限~

本文地址:http://www.cnblogs.com/zivwong/p/7434523.html

作者博客:ziv

欢迎转载,请在明显位置给出出处及链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值