文章目录
1. ViewSet
-
继承自 APIView 与 ViewSetMixin,作用也与 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
已经完成了这样的继承工作,继承自 GenericAPIView 与 ViewSetMixin,在实现了调用 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/<int:pk>', 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