drf 视图函数的使用
因为在drf的的使用中,标准化的restful的接口的views视图层,十分常见。所以就出现了使用面向对象封装的方式实现代码的复用。
最基本的实现方法:
class Books(APIView): def get(self, request): response = {'status': 100, 'msg': None} book_list = models.Book.objects.all() book_ser = Bookser(book_list, many=True) response['msg'] = book_ser.data return Response(response) def post(self, request): response = {'status': 100, 'msg': None} bookser = Bookser(data=request.data) if bookser.is_valid(): bookser.save() response['msg'] = bookser.data else: response['status'] = 101 response['error'] = bookser.errors return Response(response) class Book(APIView): def get(self,request,id): response = {'status': 100, 'msg': None} book = models.Book.objects.filter(pk=id) bookser = Bookser(book,many=True) response['msg'] = bookser.data return Response(response) def put(self,request,id): response = {'status': 100, 'msg': None} book = models.Book.objects.filter(pk=id).first() bookser =Bookser(data=request.data,instance=book) if bookser.is_valid(): bookser.save() response['msg']=bookser.data else: response['errors']=bookser.errors return Response(response) def delete(self,request,id): response = {'status': 100, 'msg': None} book = models.Book.objects.filter(pk=id).delete() return Response(response)
首先是对于增删改查等方法的封装
from rest_framework.mixins import CreateModelMixin,RetrieveModelMixin,ListModelMixin,UpdateModelMixin,DestroyModelMixin from rest_framework.generics import GenericAPIView #GenericAPIView的作用:设置基础变量 #queryset 指定了models.表名.object.all(),数据来源 #serializer_class指定了json解析类的方式 #lookup_field 指定检索在url中指定的检索的关键字 #CreateModelMixin,封装了object的 post创建记录的方法 #RetrieveModelMixin,封装object的get的查询单挑记录的方法 #ListModelMixin,封装了object的get的查询所有记录的方法 #UpdateModelMixin,封装的object的put/patch的单挑记录的更新的方法 #DestroyModelMixin,封装object的delete的删除单条记录的方法
具体实现如下:
class Publishes(ListModelMixin,CreateModelMixin,GenericAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSer def get(self,request): return self.list(request) def post(self,request): return self.create(request) class Publish(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSer 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.destroy(request,*args,**kwargs)
再让又因为,获得所有记录和添加记录通常定义在一个类中,那么使用一个类,多继承ListModelMixin,CreateModelMixin,GenericAPIView
再则查询单调记录、更新单条记录和删除单条通常定义在一个类中,那么使用一个多继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView
from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView class Publishes(ListCreateAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSer class Publish(RetrieveUpdateDestroyAPIView): queryset = models.Publish.objects.all() serializer_class = PublishSer
再次封装将ListCreateAPIView,RetrieveUpdateDestroyAPIView 继承给一个类
from rest_framework.viewsets import ModelViewSet class PublishView(ModelViewSet): queryset = models.Publish.objects.all() serializer_class = PublishSer
ModelViewSet的源码继承的类:创建之后会只有一个但是有两个get,在路由中没有办法区分,其实ModelViewSet这个已经解决这个问题
所以在url中的使用路由就是这样的
url(r'^publishes/', views.PublishView.as_view({'get':'list','post':'create'})), url(r'^publish/(?P<pk>\d+)',views.PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),