Django Rest framework 之 视图

在以前的django rest framework其余组件中,在视图函数中继承类都是rest_framework.view.APIView,这个APIView是继承的django中的View而且作了封装和方法重写的。 那么在django rest framework中,还有有没有提供其余的类可以继承?html

1、GenericAPIView

GenericAPIViewdjango rest framework中根据APIView又作了一层封装。则继承关系就变成了GenericAPIView——>APIView——>View数据库

from rest_framework.generics import GenericAPIView

class GenericView(GenericAPIView):
    queryset = Role.objects.get_queryset().order_by('id')
    serializer_class = PagerSerializer
    pagination_class = PageNumberPagination

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

        roles = self.get_queryset()
        pager_roles = self.paginate_queryset(roles)
        ser = self.get_serializer(instance=pager_roles,many=True)
        return Response(ser.data)

这里实现的功能和django rest framework 之 分页中的功能同样,先获取数据,分页,序列化返回。不一样的是,这里因为封装的做用,GenericAPIView的内部的一些方法会根据会自动的获取数据库查询结果并分页和序列化。django

  • get_queryset(): 会获取数据库查询结果,也就是queryset
  • paginate_queryset(roles):会根据重写的pagination_class属性获取分页类进行分页操做,另外若是这里没有重写,会自动到settings.py配置文件去找
  • self.get_serializer():就是根据分页后的对象进行数据的序列化,也会先找到序列化类

2、GenericViewSet

一、源码分析

GenericViewSet实际上使用了多继承和Mixin模式,也就是说GenericViewSet同时继承了ViewSetMixin, generics.GenericAPIView两个父类api

# rest_framework\viewsets.py 源码

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    pass

GenericViewSet中因为类继承的前后顺序的关系,会先执行ViewSetMixin类中相关方法。而GenericAPIView类中的相关方法会被忽略。app

二、路由

在执行以前要更改一下路由系统iview

from django.conf.urls import url

from .views import *
app_name = 'api'

urlpatterns = [
    url(r'^generic/$', GenericView.as_view()),
    url(r'^genericset/$', GenericSetView.as_view({'get': 'list', 'post': 'create'})),
]

因为在GenericViewSet的内部重写了as_view方法,且继承关系又先于GenericAPIView类,因此会进入GenericViewSetas_view方法。可是在as_view方法中,对路由系统作了略微的改动,须要对方法,作一一映射关系。即'get': 'list', 'post': 'create',get(获取单条数据)请求,会进入子类的list方法,而create(建立对象)方法则表明了post请求。函数

三、视图

视图中基本上和上面同样,只不过更改了不一样http请求方法的对应类方法名源码分析

from rest_framework.viewsets import GenericViewSet

class GenericSetView(GenericViewSet):
    queryset = Role.objects.get_queryset().order_by('id')
    serializer_class = PagerSerializer
    pagination_class = PageNumberPagination

    def list(self,request,*args,**kwargs):
        # 获取数据
        roles = self.get_queryset() # models.Role.objects.all()
        # [1, 1000,]     [1,10]
        pager_roles = self.paginate_queryset(roles)
        # 序列化
        ser = self.get_serializer(instance=pager_roles,many=True)
        return Response(ser.data)

    def create(self, request, *args, **kwargs):
        ret = {}
        try:
            title = request.data['title']
            Role.objects.create(title=title)
            print('success')
        except Exception as e:
            print(e)

四、测试

<1>、测试一

http://127.0.0.1:8000/api/genericsetget方法获取数据时,返回正常结果post

<2>、测试二

http://127.0.0.1:8000/api/genericset/,表示发送post请求添加单条数据,数据添加成功测试

3、ModelSetView

一、源码分析

ModelSetView作的更完全,他又一次继承了GenericViewSet,而且在此以前又继承了其余几个类,所以功能更多,变成了ModelViewSet——>GenericViewSet——>APIView——>View

class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
  
    pass

从这些类的名字能够大概看出,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,.ListModelMixin,分别对应,建立,获取单条数据,更新,删除,或许多条数据。

二、路由

from django.conf.urls import url
from django.urls import path

from .views import *
app_name = 'api'

urlpatterns = [
    url(r'^modelset/(?P<pk>\d+)/$', ModelSetView.as_view({'get': 'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
]

因为在获取,删除,更新数据的时候须要这顶数据的惟一标识,这里是pk主键,所以须要在url中增长正则匹配。

三、视图

在视图中,并无增长相应的增删改查的逻辑却能完成相应的功能,这是由于继承的mixin类中,已经有一一对应的方法,视图类会自动调用父类的方法。

from rest_framework.viewsets import ModelViewSet

class ModelSetView(ModelViewSet):
    queryset = Role.objects.get_queryset().order_by('id')
    serializer_class = PagerSerializer
    pagination_class = PageNumberPagination

获取第九条数据,返回结果

四、自定义

ModelSetView中看到,继承了多个mixin类,而这些类又分别封装了不一样的对应于增删给查的方法,所以若是想要自定义一个接口,实现部分http方法,就能够根据须要继承不一样的mixin

mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
相关文章
相关标签/搜索