1.框架一(繼承APIView)
這里的第一部分使用骨架請參考我的博客(第三篇),它采用了restframework中最基礎的辦法(APIView)實現了相關請求,以下的框架都是基於它的
2.框架二(繼承ViewSetMixin)
對於框架一,我們只繼承APIView,也能實現增刪改查的方法,但是不要忘了:
對於查看(get),我們可以查看全部,也能查看局部(添加id)
對於刪除,我們也要根據指定id刪除,對於修改,我們也要根據指定id修改
那么,我們就要寫兩個路由,兩個類:一個類(CoursesView)中包含了get和post方法,每個方法不用攜帶id;一個類(CourseDetailView)中包含了get,put和delete三個方法,都需要攜帶id
這樣我們操作的的類過多,每一個都要寫兩套類,那樣工作量就會很大
而框架二是在繼承APIView的基礎下,再繼承ViewSetMixin的類,來實現一套路由的管理
我們先來查看ViewSetMixin的文檔說明:
""" This is the magic. Overrides `.as_view()` so that it takes an `actions` keyword that performs the binding of HTTP methods to actions on the Resource. For example, to create a concrete view binding the 'GET' and 'POST' methods to the 'list' and 'create' actions... view = MyViewSet.as_view({'get': 'list', 'post': 'create'}) """
基於源碼我們來重寫views下的course.py
from rest_framework.views import APIView from rest_framework.viewsets import ViewSetMixin class CoursesView(ViewSetMixin,APIView): # 查看 def list(self, request, *args, **kwargs): pass # 增加 def create(self, request, *args, **kwargs): pass # 局部查看 def retrieve(self, request, pk, *args, **kwargs): pass # 指定id修改 def update(self, request, pk, *args, **kwargs): pass # 指定id刪除 def destroy(self, request, pk, *args, **kwargs): pass
api下的urls.py
from django.conf.urls import url from api.views import course urlpatterns = [ url(r'courses/$',course.CoursesView.as_view({'get':'list','post':'create'})), url(r'courses/(?P<pk>\d+)/$',course.CoursesView.as_view({'get':'retrieve','put':'update','delete':'destroy'})) ]
實際情況下,我們也不會這幾種方法都用到,主要還是查看
3.框架三(繼承ViewSetMixin和generics.GenericAPIView)
相關源碼說明:
基於源碼我們來重寫views下的course.py
from api import models from rest_framework.response import Response from api.serializers.course import CourseSerializer from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin,CreateModelMixin,\ RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,ListModelMixin # 這里我只使用了list方法,你要是用其他哪一種方法,直接把它的相關類寫進即可 class CoursesView(ListModelMixin,GenericViewSet): queryset = models.Course.objects.all() def list(self, request, *args, **kwargs): course_list = models.Course.objects.all() ser = CourseSerializer(instance=course_list, many=True) return Response(ser.data)
api下的urls.py
from django.conf.urls import url from api.views import course urlpatterns = [ url(r'courses/$',course.CoursesView.as_view({'get':'list'})), url(r'courses/(?P<pk>\d+)/$',course.CoursesView.as_view({'get':'retrieve'})) ]
serializers下的course.py(也沒有做改變)
from rest_framework import serializers class CourseSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField()
效果:
3.1基於框架三的擴展(可以使用序列化組件ModelSerializer,它繼承了Serializer)
它的相關源碼:
這里相關代碼我就不演示了,可以查看之前的代碼學習相關知識
相關說明:對於框架一和框架二適用於用戶請求處理時業務邏輯復雜的情況。
第三種框架,由於渲染器內部會調用視圖對象的get_queryset方法,所以必須要設置queryset字段。
針對第三種解決方案:
1. 設置queryset字段 class CoursesView(ListModelMixin,GenericViewSet): queryset = models.Course.objects.all() def list(self, request, *args, **kwargs): course_list = models.Course.objects.all() ser = CourseSerializer(instance=course_list, many=True) return Response(ser.data) 2. 不使用渲染器,沒有那種好看的面板渲染了 class CoursesView(ListModelMixin,GenericViewSet): renderer_classes = [JSONRenderer,] def list(self, request, *args, **kwargs): course_list = models.Course.objects.all() ser = CourseSerializer(instance=course_list, many=True) return Response(ser.data)