Django DRF 视图集

文章目录

    • 1. ViewSet
    • 2. GenericViewSet
    • 3. ModelViewSet
    • 4. ReadOnlyModelViewSet
    • 5. ViewSetMixin 源码分析
    • 6. 视图集中定义附加 action 动作
    • 7. 自动添加路由
    • 8. 总结

1. ViewSet

  • 继承自 APIViewViewSetMixin,作用也与 APIView 基本类似,提供了身份认证、权限校验、流量管理等。

  • ViewSet 主要通过继承 ViewSetMixin 来实现在调用 as_view() 时传入字典(如{‘get’:’list’})的映射处理工作。

  • 在ViewSet中,没有提供任何动作 action 方法,需要我们自己实现 action 方法。

  • 源码如下

class ViewSet(ViewSetMixin, views.APIView):
    pass

使用ViewSet通常并不方便,因为 list、retrieve、create、update、destory 等方法都需要自己编写

2. GenericViewSet

由于使用 ViewSet 需要自己编写方法。我们可以通过继承 Mixin 扩展类来复用这些方法而无需自己编写。但是 Mixin 扩展类依赖与 GenericAPIView,所以还需要继承 GenericAPIView。

GenericViewSet 已经完成了这样的继承工作,继承自 GenericAPIViewViewSetMixin,在实现了调用 as_view() 时传入字典(如{‘get’:‘list’})的映射处理工作的同时,还提供了 GenericAPIView 提供的基础方法,可以直接搭配 Mixin 扩展类使用。

视图函数

from app01 import models
from app01.serializer import BookSerializer

from rest_framework.viewsets import GenericViewSet

from rest_framework.mixins import ListModelMixin,CreateModelMixin
from rest_framework.mixins import RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

class BookView(GenericViewSet, ListAPIView, CreateAPIView):
    queryset = models.Book.objects
    serializer_class = BookSerializer

路由

from django.contrib import admin
from django.urls import path
from app01.view import views6

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views6.BookView.as_view({'get': 'list', 'post': 'create'})),
]

GenericViewSet 源码

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    pass

3. ModelViewSet

继承自 GenericViewSet,同时包括了 ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

视图函数

from app01 import models
from app01.serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet

class BookView(ModelViewSet):
    queryset = models.Book.objects
    serializer_class = BookSerializer

路由

from django.contrib import admin
from django.urls import path
from app01.view import views6

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views6.BookView.as_view({'get': 'list', 'post': 'create'})),
    path('books/', views6.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]

查看源码

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

    pass

4. ReadOnlyModelViewSet

继承自 GenericViewSet,同时包括了 ListModelMixin、RetrieveModelMixin。

查看源码

class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet):

    pass

5. ViewSetMixin 源码分析

class ViewSetMixin:
    @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
        ...
        # actions={'get': 'list', 'post': 'create'}
        def view(request, *args, **kwargs):
			...
			# method:get    action:list
            for method, action in actions.items():
            	# handler = getattr(self, list),handler 等同于 list
                handler = getattr(self, action)
                # setattr(self, get, list) 反射:把list变成了get
                setattr(self, method, handler)
			
			...
            return self.dispatch(request, *args, **kwargs)
        ...
        return csrf_exempt(view)
	...

6. 视图集中定义附加 action 动作

查看源码发现其是通过反射来映射的,因此在视图类中可以编写任意名称的方法,如下示例

视图函数

from app01 import models
from rest_framework.response import Response
from app01.serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet

class BookView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def login(self, request):
        return Response({'code': 101})

路由

from django.contrib import admin
from django.urls import path
from app01.view import views, views1, views2, views3, views4, views5, views6

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views6.BookView.as_view({'get': 'list', 'post': 'login'})),
]

在路由中添加自定义的方法名即可。

在视图集中可以通过 action 对象属性来获取当前请求视图集时的 action动作是哪个。

print(self.action)

7. 自动添加路由

除了在路由中的 as_view 添加字典外,还可以自动添加。

  • 第一步,导入 include,还有 SimpleRouter, DefaultRouter
  • 第二步,对 SimpleRouter 实例化
  • 第三步,注册路由
  • 第四步,在总路由中注册。
from django.contrib import admin
from django.urls import path, include
from app01.view import views6

# 1. 导入
from rest_framework.routers import SimpleRouter, DefaultRouter

# 2. 实例化
router = SimpleRouter()
# router = DefaultRouter()  # 它会给每个注册的视图类都生成一个根路由

# 3. 注册路由,参数分别表示,路由前缀、视图函数名、别名
router.register('books', views6.BookView, 'books')

# djagno框架中,顶格写的代码,djagno一运行就会运行
print(router.urls)  # 能自动生成路由

urlpatterns = [
    path('admin/', admin.site.urls),
    # 4. 在总路由中注册  
    # 注册方式一
    path('', include(router.urls)),
    
    # 注册方式二
    # path('books', views.BookView.as_view({'get': 'lqz', 'post': 'login'})),
]

8. 总结

基类

  • APIView
  • GenericAPIView (有关数据库操作 queryset 和serializer_class)

视图扩展类

  • CreateModelMixin:create方法创建一条
  • DestroyModelMixin:destory方法删除一条
  • ListModelMixin:list方法获取所有
  • RetrieveModelMixin:retrieve获取一条
  • UpdateModelMixin:update修改一条

视图子类

  • CreateAPIView: 继承 CreateModelMixin,GenericAPIView,有post方法,新增数据
  • DestroyAPIView:继承 DestroyModelMixin,GenericAPIView,有delete方法,删除数据
  • ListAPIView:继承 ListModelMixin,GenericAPIView,有get方法获取所有
  • UpdateAPIView:继承 UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据
  • RetrieveAPIView:继承 RetrieveModelMixin,GenericAPIView,有get方法,获取一条
  • ListCreateAPIView:继承ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增
  • RetrieveDestroyAPIView:继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除
  • RetrieveUpdateAPIView:继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改
  • RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除

视图集

  • ViewSet: 继承ViewSetMixin和APIView
  • ViewSetMixin:重写了as_view
  • GenericViewSet:继承ViewSetMixin, generics.GenericAPIView
  • ModelViewSet:继承mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet
  • ReadOnlyModelViewSet:继承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet

你可能感兴趣的:(Django,框架,django,python,restful)