首页 > 技术文章 > drf 视图函数的使用

msj513 2019-02-25 21:12 原文

因为在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)
View Code

首先是对于增删改查等方法的封装

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'})),

 

推荐阅读