DRF Django REST framework 之 视图组件(四)

水痕 2019-12-12

引言

在我们有几十上百的视图类,都有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

~>.<~

相关推荐