此时,我们有两个类视图,ProjectViewProjectDetailView,我们来看看有啥区别,一个是没有传id的,一个是传了id的,但是两个类视图中的queryset和serializer_class都是一样的,那么我们有没有什么办法只写一个类视图呢?有,使用GenericViewSet。

GenericViewSet

  • 继承ViewSetMixin和GenericAPIView
    • ViewSetMixin具备给as_view传递字典参数,key为请求方法名称(get、post、put、delete),value为需要调用的action方法名称。
    • GenericAPIView提供get_queryset,get_serializer、get_object等,支持过滤、排序和分页的操作

打开**project\views.py**,注释**ProjectView****ProjectDetailVie**类,新增ProjectViewSet类,修改代码如下

  1. from .models import Projects
  2. from .serializers import ProjectsModelSerializer
  3. from rest_framework import filters, viewsets, mixins
  4. class ProjectViewSet(mixins.CreateModelMixin,
  5. mixins.RetrieveModelMixin,
  6. mixins.UpdateModelMixin,
  7. mixins.DestroyModelMixin,
  8. mixins.ListModelMixin, viewsets.GenericViewSet):
  9. # 一般需要指定queryset、serializer_class类属性
  10. queryset = Projects.objects.all()
  11. serializer_class = ProjectsModelSerializer
  12. # 指定过滤引擎
  13. filter_backends = [filters.SearchFilter, filters.OrderingFilter]
  14. # 过滤的字段
  15. search_fields = ['name', 'desc']
  16. ordering_fields = ['name']

修改路由

既然我们不用ProjectViewProjectDetailView,改用ProjectViewSet,那么我们的路由也得改变
修改**caseplatform\url.py**

  1. urlpatterns = [
  2. path('admin/', admin.site.urls),
  3. path('projects/<int:pk>/', views.ProjectViewSet.as_view()),
  4. path('projects/', views.ProjectViewSet.as_view()),
  5. ]

修改后,发现报如下错误,我们来看看是什么意思,大概是说如果我们使用ViewSet,那么调as_view()时必须传一个参数,可以修改为.as_view({‘get’: ‘list’})
image-20220317144724139.png
继续修改**caseplatform\urls.py**

  1. from django.contrib import admin
  2. from django.urls import path
  3. from project import views
  4. urlpatterns = [
  5. path('admin/', admin.site.urls),
  6. path('projects/<int:pk>/', views.ProjectViewSet.as_view({
  7. 'get': 'retrieve',
  8. 'put': 'update',
  9. 'delete': 'destroy'
  10. })),
  11. path('projects/', views.ProjectViewSet.as_view({
  12. 'get': 'list',
  13. 'post': 'create'
  14. })),
  15. ]

ok,我们继续用postman测试下,测试过程省略。

新增应用路由

我们现在只有一个project应用,如果应用很多,所有的路由都写在caseplatform\urls.py里面,那么会比较难管理,所以我们一般会在每个应用下面新增urls.py文件
新增project\urls.py文件

  1. from django.urls import path
  2. from project import views
  3. urlpatterns = [
  4. path('projects/<int:pk>/', views.ProjectViewSet.as_view({
  5. 'get': 'retrieve',
  6. 'put': 'update',
  7. 'delete': 'destroy'
  8. })),
  9. path('projects/', views.ProjectViewSet.as_view({
  10. 'get': 'list',
  11. 'post': 'create'
  12. })),
  13. ]

修改caseplatform\urls.py文件

  1. from django.contrib import admin
  2. from django.urls import path, include
  3. urlpatterns = [
  4. path('admin/', admin.site.urls),
  5. path('', include('project.urls')),
  6. ]

ok,我们继续用postman测试下,测试过程省略。

SimpleRouter优化路由

修改**project\urls.py**

  1. from project import views
  2. from rest_framework import routers
  3. router = routers.SimpleRouter()
  4. router.register('projects', views.ProjectViewSet)
  5. urlpatterns = router.urls

ok,我们继续用postman测试下。测试过程省略。

ModelViewSet

  • 继承mixins.CreateModelMixin、mixins.RetrieveModelMixin、mixins.UpdateModelMixin、mixins.DestroyModelMixin、mixins.ListModelMixin和GenericViewSet

打开**project\views.py**,注释**ProjectView****ProjectDetailVie**类,新增ProjectViewSet类,修改代码如下

  1. from .models import Projects
  2. from .serializers import ProjectsModelSerializer
  3. from rest_framework import filters, viewsets
  4. class ProjectViewSet(viewsets.ModelViewSet):
  5. # 一般需要指定queryset、serializer_class类属性
  6. queryset = Projects.objects.all()
  7. serializer_class = ProjectsModelSerializer
  8. # 指定过滤引擎
  9. filter_backends = [filters.SearchFilter, filters.OrderingFilter]
  10. # 过滤的字段
  11. search_fields = ['name', 'desc']
  12. ordering_fields = ['name']

ok,我们继续用postman测试下。测试过程省略。