DRF框架之檢視集、Routers路由
阿新 • • 發佈:2020-07-19
先上程式碼:
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 importProjectsModelSerializer 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' })) ]