一 、ViewSet
1、当前两个类视图的请求方法、对应的方法(动作)和描述
我们是否可以把路由和动作给进行映射?如果获取单条详情数据,则执行retrieve
,如果获取多条详情数据,则执行list
...
请求方法 | 动作 | 描述 |
---|---|---|
GET | retrieve | 获取详情数据/单条 |
GET | list | 获取详情数据/多条 |
POST | create | 创建数据 |
PUT | update | 更新数据 |
PATCH | partial_update | 部分更新 |
DELETE | destory | 删除数据 |
2、ViewSet
-
ViewSet
继承ViewSetMixin
和views.APIView
-
ViewSet
支持list
、retrieve
等action方法,不支持get
、post
等请求方法 -
ViewSet
不提供get_object()
、queryset
、serializer_class
等方法
我们需要使用支持第三点所说的这些的类:GenericViewSet
二、最终方案
2.1、继承GenericViewSet
-
GenericViewSet
支持get_object()
、queryset
、serializer_class
等方法 -
GenericViewSet
不支持list
、retrieve
等action方法 - 所解决的痛点:可以让路由和action方法进行映射,但是缺点是需要把
list
、retrieve
等action方法复制到当前视图类中
2.2、mixins
- 如果要解决单单继承
GenericViewSet
所带来的的缺点,那么就需要继承上一文中的mixins
中的几个类:ListModelMixin
、ListModelMixin
等类
2.3、viewsets.ModelViewSet
综上所述,我们最终需要的是一个继承了GenericViewSet
和mixins
这些类的类,然后我们的视图类,再去继承它。
这个类就是viewsets.ModelViewSet
三、最终代码
-
views.py
视图类
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from projects.models import Projects
from projects.serializer import ProjectModelSerializer
class ProjectsViewSet(viewsets.ModelViewSet):
ordering_fields = ['name', 'leader']
queryset = Projects.objects.all()
serializer_class = ProjectModelSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields =['name', 'desc']
-
urls.py
路由设置(url、请求方式和action进行映射)
from django.urls import path
from projects import views
urlpatterns = [
# 没有id的url
path('project/', views.ProjectsViewSet.as_view({
# 请求方式和action的映射
'get': 'list',
'post': 'create'
}), name='projects_list'),
# 带id的url
path('project/<int:pk>/', views.ProjectsViewSet.as_view({
# 请求方式和action的映射
'get':'retrieve',
'put': 'update',
'delete':'destroy'
}), name='project_detail'
)]
三、View
的总结
-
Django
中:
1.View
类 -
DRF
中:
1.APIView
2.GenericAPIView
3.mixins
拓展类
4.CreateAPIView
(合并拓展类) -
(
DRF
):url、请求方式和action的映射
5.ViewSet
视图集
6.GenericViewSet
7.CreateViewSet
8.ModelViewSet
网友评论