1. 程式人生 > >DRF Django REST framework 之 檢視元件(四)

DRF Django REST framework 之 檢視元件(四)

引言

在我們有幾十上百的檢視類,都有get,post等方法,在功能類似時,會導致大量的重複程式碼出現,顯然還有很多可以優化的地方。這也就有了檢視元件,它的功能非常強大,能很好的優化介面邏輯。

檢視元件

使用檢視元件的mixin優化介面邏輯

  1. 匯入 mixins 
  2. 定義序列化類
  3. 定義檢視類
# 1.匯入mixins
from rest_framework.mixins import (
    ListModelMixin,
    CreateModelMixin,
    DestroyModelMixin,
    UpdateModelMixin,
    RetrieveModelMixin
)
from rest_framework.generics import GenericAPIView

from DrfOne import models
# 2.定義序列化類
from DrfOne.drf_serializers import BookSerializer


# 3.定義檢視類
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
    # 獲取資料來源, 固定寫法
    queryset = models.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 = models.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)

定義序列化類

from rest_framework import serializers

from DrfOne import models


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = "__all__"
        extra_kwargs = {
            # 僅寫
            "publish": {'write_only': True},
            "authors": {'write_only': True},
        }

    publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name")
    publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address")
    author_name = serializers.SerializerMethodField()

    def get_author_name(self, book_obj):
        author_list = list()
        for author in book_obj.authors.all():
            # 注意列表新增欄位,author.name而不是author
            author_list.append(author.name)
        return author_list

注意:操作單條資料的 url 

from django.urls import path, re_path

from DrfOne import views

urlpatterns = [
    path('books/', views.BookView.as_view()),
    # 需要命名為pk
    re_path("books/(?P<pk>\d+)/", views.BookFilterView.as_view()),
]

通過上面程式碼發現 get , post 等方法內容相似,可以進行再次封裝。

使用檢視元件的view優化介面邏輯

  1. 匯入 generics 
  2. 匯入序列化類
  3. 定義檢視類

對 mixins 再次優化其餘內容不變

# 1.匯入generics
from rest_framework import generics

from DrfOne import models
# 2.匯入序列化類
from DrfOne.drf_serializers import BookSerializer


# 3.定義檢視類
class BookView(generics.ListCreateAPIView):
    # 獲取資料來源, 固定寫法
    queryset = models.Book.objects.all()
    # 序列化類, 固定寫法
    serializer_class = BookSerializer


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

發現還是有重複程式碼,再次優化,也就是 viewset 。

使用檢視元件的viewset優化介面邏輯

看似已經優化的非常完美了,但是在一個對效能要求極高的專案裡面,我們的程式還可以繼續優化,不斷的優化程式是每個程式設計師必備的技能。

  1. 定義 url 
  2. 匯入 viewset 
  3. 匯入序列化類
  4. 定義檢視類

注意urls.py的變化

from django.urls import path, re_path

from DrfOne import views


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

    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

# 2.匯入viewset模組裡的ModelViewSet類
from rest_framework.viewsets import ModelViewSet

# 匯入應用裡的models
from DrfOne import models
# 3.匯入序列化類
from DrfOne.drf_serializers import BookSerializer

# 4.定義檢視類
class BookView(ModelViewSet):
    # 獲取資料來源, 固定寫法
    queryset = models.Book.objects.all()
    # 序列化類, 固定寫法
    serializer_class = BookSerializer

~>.&