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

posted @ 2020-07-19 15:57  小公瑾  阅读(495)  评论(0编辑  收藏  举报