DRF通用view

幾種view以及他們之間的關係

 View是Django中的

APIView

APIView是對Django中View的封裝,和View相比,APIView大致有以下不同:

1.傳遞給處理方法的請求是DRF的Request實例,而不是Django的HttpRequest實例;
2.響應並返回的是DRF的Response對象,而不是Django的HttpResponse對象;
4.會對接收的請求進行身份認證、權限的檢查以及限制訪問次數。

 APIView使用方法如下:
 

from rest_framework.views import APIView
from rest_framework.response import Response

class SchoolView(APIView):
    def get(self, request, *args, **kwargs):
        query_set = models.School.objects.all()
        ser_obj = app01_serializers.SchoolSerializer(query_set, many=True)
        return Response(ser_obj.data)

GenericApiView

GenericApiView繼承於APIView,爲常用的列表視圖和詳細視圖提供了一些操作屬性方法。

示例:

from rest_framework import generics
from rest_framework import mixins

class SchoolView(GenericAPIView, mixins.ListModelMixin):
    queryset = models.School.objects.all()
    serializer_class = app01_serializers.SchoolSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

GenericAPIViewAPIView再次封裝,加入了以下功能:

  • 加入queryset屬性,可以直接設置這個屬性,不必再將實例化的courses,再次傳給seriliazer,系統會自動檢測到。除此之外,可以重載get_queryset(),這樣就不必設置’queryset=*’,這樣就變得更加靈活,可以進行完全的自定義。
  • 加入serializer_class屬性與實現get_serializer_class()方法。兩者的存在一個即可,通過這個,在返回時,不必去指定某個serilizer
  • 設置過濾器模板:filter_backends(排序,過濾,搜索)
  • 設置分頁模板:pagination_class
  • 加入 lookup_field=”pk”,以及實現了get_object方法: 這個用得場景不多,但十分重要。它們兩者的關係同1,要麼設置屬性,要麼重載方法。它們的功能在於獲取某一個實例時,指定傳進來的後綴是什麼。

 通常GenericAPIView不會單獨使用,GenericAPIView需要和Mixins組合使用。

Mixin類中提供了許多用於對視圖進行操作的方法,這些操作方法無須我們自己實現就可以使用了。比如,ListModelMixin提供了一個list()方法用於將Model的查詢集響應給客戶端。

generics.py文件中還存在一些通用類,可以使代碼的編寫更加簡單。

 簡化之後如下:

class SchoolView(ListCreateAPIView):
    #使用通用類
    queryset = models.School.objects.all()
    serializer_class = app01_serializers.SchoolSerializer

 

GenericViewSet

GenericViewSet繼承了ViewSetMixinGenericAPIView,在ViewSetMixin類中重寫了as_view方法,可以這樣使用路由:

url(r'school/$', views.SchoolView.as_view({
    "get": "list",
    "post": "create",
})),

 

視圖集ModelViewSet

集成了上面所有的類,非常好用

class SchoolView(ModelViewSet):
    queryset = models.School.objects.all()
    serializer_class = app01_serializers.SchoolSerializer

高級路由

route方法註冊與綁定

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'school', views.SchoolView)
urlpatterns += router.urls

route中使用的一定要是ViewSet,用router.register的方法註冊url可以很好的管理url,不會導致url過多而混亂。

 

補充:DRF中的Request和Resopnse

1. Request

在DRF中內置的Request類擴展了Django中的Request類,實現了很多方便的功能--如請求數據解析和認證等。

Request對象的數據是自動根據前端發送數據的格式進行解析之後的結果。

無論前端發送的哪種格式的數據,我們都可以以統一的方式讀取數據。
常用屬性

  •  .data

request.data 返回解析之後的請求體數據。類似於Django中標準的request.POST和 request.FILES屬性,但提供如下特性:

    包含了解析之後的文件和非文件數據
    包含了對POST、PUT、PATCH請求方式解析後的數據
    利用了DRF的parsers解析器,不僅支持表單類型數據,也支持JSON數據

  •  .query_params

request.query_params與Django標準的request.GET相同,只是更換了更正確的名稱而已。

2 Response

DRF提供了一個響應類Response,使用該類構造響應對象時,響應的具體數據內容會被轉換(render渲染)成符合前端需求的類型。

DRF提供了Renderer 渲染器,用來根據請求頭中的Accept(接收數據類型聲明)來自動轉換響應數據到對應格式。如果前端請求中未進行Accept聲明,則會採用默認方式處理響應數據,可以通過配置來修改默認響應格式。

    REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': (  # 默認響應渲染類
            'rest_framework.renderers.JSONRenderer',  # json渲染器
            'rest_framework.renderers.BrowsableAPIRenderer',  # 瀏覽API渲染器
        )
    }

構造方式

Response(data, status=None, template_name=None, headers=None, content_type=None)

參數:

    data: 爲響應準備的序列化處理後的數據;
    status: 狀態碼,默認200;
    template_name: 模板名稱,如果使用HTMLRenderer 時需指明;
    headers: 用於存放響應頭信息的字典;
    content_type: 響應數據的Content-Type,通常此參數無需傳遞,REST framework會根據前端所需類型數據來設置該參數。

常用屬性:

  • .data

傳給response對象的序列化後,但尚未render處理的數據

  • .status_code

狀態碼的數字

  • .content

經過render處理後的響應數據

  • 3. 狀態碼

返回狀態信息。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章