DRF(3) - 序列化組件(GET/PUT/DELETE接口設計)、視圖優化組件

1、序列化組件

  基於上篇隨筆的表結構,經過序列化組件的ModelSerializer設計以下三個接口:python

GET       127.0.0.1:8000/books/{id}    # 獲取一條數據,返回值:{}
PUT       127.0.0.1:8000/books/{id}    # 修改數據,返回值:{}
DELETE    127.0.0.1:8000/books/{id}    # 刪除數據,返回空

  urls.py文件:程序員

from django.urls import path, re_path
from serializer import views
urlpatterns = [
    re_path('books/(\d+)/$', views.BookFilterView.as_view())
]

  Views.py文件:django

class BookFilterView(APIView):
    def get(self, request, nid):
        book_obj = Book.objects.get(pk=nid)
        serialized_data = BookSerializer(book_obj, many=False)
        return Response(serialized_data.data)

    def put(self, request, nid):
        book_obj = Book.objects.get(pk=nid)
        verified_data = BookSerializer(data=request.data, instance=book_obj, many=False)
        if verified_data.is_valid():
            verified_data.save()
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)

    def delete(self, request, nid):
        Book.objects.get(pk=nid).delete()
        return Response()

2、視圖組件引入

  前面的介紹中,咱們已經經過序列化組件設計除了符合REST規範的五個經常使用接口,如今假設,咱們有多個數據接口,好比(Book,Author,Publish...)等數據表都須要定義相似的接口,能夠預見,咱們須要重複定義相似上面的五個接口,這種方式將會致使大量的重複代碼,顯然,咱們的程序還有不少須要優化的地方,那麼,若是是你,將會如何進行優化呢?編程

  首先回顧如下混入類和多繼承的知識,有以下一個Animal類:網絡

class Animal(object):
    def eat(self):
        print("Eating")

    def sleepping(self):
        print("sleepping")
class Bird(Animal):   def flying(self):   print("flying") class Bee(Animal):   def flying(self):   print("flying")

  此時,咱們能夠改成以下代碼(python支持多繼承,不是全部語言都有這個特色):app

class Animal(object):
    def eat(self):
        print("Eating")

    def sleepping(self):
        print("sleepping")

class Flying(object):
    def flying(self):
      print("flying")

class Bird(Animal, Flying):
  pass

class Bee(Animal, Flying):
  pass

  看到這裏,結合上面的回顧的混合類和多繼承,咱們是否可使用下面的方式優化以前的接口設計呢?socket

class GetAllData():
    def get(self, request):pass

class GetOneData():
    def get(self, request):pass

class DeleteOneData():
    def delete(self, request):pass

class UpdateOneData():
    def put(self, request):pass

class CreateData():
    def post(self, request):pass

class BookView(APIView, GetAllData, CreateData):pass

class BookFilterView(APIView, GetOneData, DeleteOneData, UpdateOneData):pass

  像上面代碼這樣,將每一個接口都寫到獨立的類中,而後使用多繼承,或者成爲mixin的這種方式,就能夠對咱們的程序進行優化,mixin的方式很是常見,在網絡編程中學過的socketserver,其源碼中就有對mixin的實現,即,假設咱們須要進程的時候,咱們繼承進程類,若是咱們須要線程的時候,咱們就繼承線程類便可。post

3、視圖組件使用

  視圖組件是用來優化接口邏輯的。性能

一、使用視圖組件的mixin進行接口邏輯優化,上面五個接口能夠改寫以下:優化

  urls.py代碼:

from django.urls import re_path
from serializer import views

urlpatterns = [
    re_path('books/$', views.BookView.as_view()),
    re_path('books/(?P<pk>\d+)/$', views.BookFilterView.as_view()),
]

  視圖views.py代碼:

from rest_framework.mixins import (
    ListModelMixin,
    CreateModelMixin,
    DestroyModelMixin,
    UpdateModelMixin,
    RetrieveModelMixin
)
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
# 導入序列化類
from .app_serializers import BookSerializer
from .models import Book, Publish, Author

class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
    # queryset和serializer_class是固定寫法
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class BookFilterView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

  注意:單條數據操做的url有變化,由於咱們在視圖中,統一傳的都是queryset,因此,須要經過傳入一個名爲pk的命名參數,告訴視圖組件,用戶須要操做的具體數據。

二、使用視圖組件的genericview進行接口邏輯優化

  上面的代碼看似已經優化的很是完美了,可是,在一個對性能要求極高的項目裏面,咱們的程序還能夠繼續優化,不斷優化程序是每一個程序員必備的技能,也是幫助咱們成長的重要手段。一樣的思路,一樣的方法,咱們能夠將多個接口封裝到一個功能類中,以下代碼:

from rest_framework import generics

from .app_serializers import BookSerializer
from .models import Book, Publish, Author

class BookView(generics.ListCreateAPIView):
     queryset = Book.objects.all()
     serializer_class = BookSerializer

class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

三、使用視圖組件的viewset進行接口邏輯優化

  上面的代碼已經看似很是完美了,可是,你有沒有發現還有重複代碼,該如何改進呢?使用viewset能夠進一步優化,以下:

  urls.py文件(注意跟以前有什麼不一樣):

from django.urls import re_path
from serializer import views

urlpatterns = [
    re_path('books/$', views.BookView.as_view({
        'get': 'list',
        'post': 'create'
    })),
    re_path('books/(?P<pk>\d+)/$', views.BookView.as_view({
        'get': 'retrieve',
        'put': 'update',
        'delete': 'destroy'
    }))

  視圖views.py部分:

from rest_framework.viewsets import ModelViewSet
from .app_serializers import BookSerializer
from .models import Book, Publish, Author

class BookView(ModelViewSet):
     queryset = Book.objects.all()
     serializer_class = BookSerializer

  使用方式是否是很簡單,接下來去看如下源碼都爲咱們作了什麼吧!其實整個viewset優化方案最重要的地方就是urls.py中傳入了參數,而後對參數進行映射關係綁定。

相關文章
相關標籤/搜索