• DRF框架之视图集、Routers路由


    先上代码:

    from django_filters.rest_framework import DjangoFilterBackend
    from rest_framework.filters import OrderingFilter
    from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
    from utils.pagination import NewPagination
    from .models import Projects
    from .serializers import ProjectsModelSerializer
    
    
    class ProjectsPage(ListCreateAPIView):
        '''
        类视图
        '''
        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
    
    
    class ProjectsDetailsPage(RetrieveUpdateDestroyAPIView):
    
        queryset = Projects.objects.all()
        serializer_class = ProjectsModelSerializer

    我们现在想将两个视图进行合并,要怎么操作呢?直接合并我们发现有以下痛点:

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

    因此这里引出了视图集,将视图集与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

    开始的代码优化如下:

    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
    
        filter_backends = [DjangoFilterBackend, OrderingFilter]
        filterset_fields = ['id', 'name', 'leader', 'programmer', 'tester']
        ordering_fields = ['id', 'name', 'leader', 'programmer', 'tester']
        pagination_class = NewPagination

    关于继承,可以使用ModelViewSet替换所有的继承:

    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
    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/<int:pk>/', ProjectsPageSet.as_view({
            'get': 'retrieve',
            'put': 'update',
            'delete': 'destroy'
        }))
    ]

    针对路由依然可以做优化

    1.SimpleRouter

    1.引入方式

    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.访问根路径

    如果不想根路径返回404页面,那么可以用下面这种方式

    2.DefaultRouter

    1.引入方式

    from rest_framework.routers import DefaultRouter

    2.创建对象

    router = DefaultRouter()

    后面的步骤一致

    3.访问根路径

  • 相关阅读:
    JS字符串截取(获取指定字符后面的所有字符内容)
    vue图片上传插件
    php获取两个日期之间的所有日期
    laravel做定时任务时,加参数(也可缓存参数)
    前端传参数(数组,值为json字符串),后端接收json_decode()转为数组,数组为空值
    springboot的maven多模块项目
    如何给文件重命名
    springboot的get请求和post请求
    java调用ffmpeg
    mybatis批量插入List
  • 原文地址:https://www.cnblogs.com/xiaogongjin/p/13340013.html
Copyright © 2020-2023  润新知