前面进行优化,但是会发现有一些局限,看下面代码

  1. from django_filters.rest_framework import DjangoFilterBackend
  2. from rest_framework.filters import OrderingFilter
  3. from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
  4. from utils.pagination import NewPagination
  5. from .models import Projects
  6. from .serializers import ProjectsModelSerializer
  7. class ProjectsPage(ListCreateAPIView):
  8. '''
  9. 类视图
  10. '''
  11. queryset = Projects.objects.all()
  12. serializer_class = ProjectsModelSerializer
  13. filter_backends = [DjangoFilterBackend, OrderingFilter]
  14. filterset_fields = ['id', 'name', 'leader', 'programmer', 'tester']
  15. ordering_fields = ['id', 'name', 'leader', 'programmer', 'tester']
  16. pagination_class = NewPagination
  17. class ProjectsDetailsPage(RetrieveUpdateDestroyAPIView):
  18. queryset = Projects.objects.all()
  19. serializer_class = ProjectsModelSerializer

两个视图类,意味着需要两个url来进行访问,总结一下当前痛点

  • 两个视图类不能合并
  • 有两个相同的get方法
  • 两个类视图所对应的url地址不一致

借此引出ViewSet,将式突击与mixins结合使用,解决上面的问题

一,视图集

请求方法 动作(action) 描述
GET retrieve 获取详情数据(单条)
GET list 获取列表数据(多条)
POST create 创建数据
PUT update 更新数据
PATCH partail_update 更新部分数据
DELETE destroy 删除数据

1,ViewSet类

  • 继承ViewSetMixin和Views.APIView
    • ViewSetMixin支持action动作
  • 未提供get_onject()、get_serializer()、queryset、serializer_class等,因此不支持过滤、排序和分页的操作

    2,GenericViewSet类

  • 继承ViewSetMixin 和 generic.GenericAPIView

    • 提供get_onject()、get_serializer()、queryset、serializer_class等,支持过滤、排序和分页的操作
  • 在定义路由时,需要将请求方法与action动作进行绑定
  • 使用Mixin类简化程序

    3,ReadOnlyModelViewSet类

  • 继承mixins.RetrieveModelMixin、mixins.ListModelMixin和generic.GenericAPIView

    4,ModelViewSet类

  • 继承mixins.CreateModelMixin、mixins.RetrieveModelMixin、mixins.UpdateModelMixin、mixins.DestroyModelMixin、mixins.ListModelMixin和generic.GenericAPIView ```python from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter from rest_framework.viewsets import GenericViewSet from rest_framework import mixins from utils.pagination import NewPagination from .models import Projects from .serializers import ProjectsModelSerializer

class ProjectsPageSet(mixins.ListModelMixin, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericViewSet): ‘’’ 类视图 ‘’’ queryset = Projects.objects.all() serializer_class = ProjectsModelSerializer

  1. filter_backends = [DjangoFilterBackend, OrderingFilter]
  2. filterset_fields = ['id', 'name', 'leader', 'programmer', 'tester']
  3. ordering_fields = ['id', 'name', 'leader', 'programmer', 'tester']
  4. pagination_class = NewPagination
最终可以使用modelViewSet替换所有的继承。
```python
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
from rest_framework.viewsets import ModelViewSet
from utils.pagination import NewPagination
from .models import Projects
from .serializers import ProjectsModelSerializer


class ProjectsPageSet(ModelViewSet):
    '''
    类视图
    '''
    queryset = Projects.objects.all()
    serializer_class = ProjectsModelSerializer

    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_fields = ['id', 'name', 'leader', 'programmer', 'tester']
    ordering_fields = ['id', 'name', 'leader', 'programmer', 'tester']
    pagination_class = NewPagination

二,Routers路由

  • 视图类继承了视图集之后,支持在定义路由时指定请求方法与action进行映射
  • as_view()需要接受一个字典,key为请求方法名,value为指定需要调用的action ```python from django.contrib import admin from django.urls import path from projects.views import ProjectsPageSet

urlpatterns = [ path(‘admin/‘, admin.site.urls), path(‘projects/‘, ProjectsPageSet.as_view({ ‘get’: ‘list’, ‘post’: ‘create’ })), path(‘projects//‘, ProjectsPageSet.as_view({ ‘get’: ‘retrieve’, ‘put’: ‘update’, ‘delete’: ‘destroy’ })) ]

针对路由依然可以做优化
<a name="mSza3"></a>
## 1,SimpleRouter
<a name="Jzsep"></a>
### 1,引入方式
```python
from rest_framework.routers import SimpleRouter

2,创建路由对象

router = SimpleRouter()

3,注册路由

router对象传入的参数,prefix为指定路由前缀(r’子应用名小写’,如果是在子应用下定义路由,可以设置为空),viewset直接指定视图集类

router.register(prefix=r'projects', viewset=ProjectsPageSet)

4,添加路由

使用路由对象.urls属性来获取自动生成的路由条目,获取的值为一个列表,并将该列表添加到urlpatterns列表当中

urlpatterns += router.urls

5,访问根路径

DRF-ViewSet & Routers - 图1

  • 不想根路径返回404页面,采用下面这种途径

    2,DefaulRouter

    1,引入方式

    from rest_framework.routers import DefaultRouter
    

    2,创建对象

    router = DefaultRouter()
    
    后面步骤一直

    3,访问根路径

    DRF-ViewSet & Routers - 图2