rest_framework(7)ListModelMixin, CreateModelMixin, RetrieveModelMixin, ListCreateAPIView

本系列文章中的上一篇文章:GenericAPIView

使用 GenericAPIView 存在的问题

现假如需要对另一张表(Author)进行增删改查操作,可以发现以下代码中除了 queryset 和 serializer_class 不一样以外,每个方法中的处理逻辑一样,如 get 方法都是查找数据然后返回,现在可以考虑把各个请求方法中的处理逻辑抽取出来,rest_framework.mixins 中实现了这个需求

from rest_framework import serializers
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

from .models import Book, Author


class BookViewSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"


class AuthorViewSerializers(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = "__all__"


class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookViewSerializers

    def get(self, request):
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)

        return Response(serializer.data)

    def post(self, request):
        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


class AuthorView(GenericAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorViewSerializers

    # 获取所有作者信息,即查看所有
    def get(self, request):
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)

        return Response(serializer.data)

    def post(self, request):
        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)

rest_framework.mixins

导入 rest_framework.mixins 中的几个类:ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

"""
ListModelMixin:查询所有对象,用于获取多个对象的 get 请求方法中,如查询所有书籍信息
CreateModelMixin:向数据库增加一条记录,用于增加数据的 post 请求方法中,如新增一本书籍信息
RetrieveModelMixin:查询单个对象信息,用于获取单个对象的 get 请求方法中,如根据 id 获取一本书籍信息
UpdateModelMixin:用于更新单个对象信息,用于更新部分或全部信息的 put 请求方法中,如根棍 id 为 1 的书籍的名称
DestroyModelMixin:用于删除单个对象信息,用于删除对象的 delete 请求方法中,如删除 id 为 1 的书籍

上述五个 Mixin 类的源码中处理逻辑和之前写的对应的 get、post、put、delete 方法中的处理逻辑一样
所以可以直接在方法中直接继承调用
如以下修改 AuthorView 类的代码
"""
# BookView 也能做同样的改变
class AuthorViewModify(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Author.objects.all()
    serializer_class = AuthorViewSerializers

    # 获取所有作者信息,即查看所有
    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)

rest_framework.mixins 中的部分类的源码

"""
ListModelMixin 源码如下
由源码可知 ListModelMixin 中的 list 方法的逻辑和 BookView、AuthorView 中的 get 方法的实现逻辑一致
class ListModelMixin:
    # ListModelMixin 的功能就是获取所有对象集合 => queryset.all()
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        # ...

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
"""


"""
CreateModelMixin 源码如下
由源码可知 CreateModelMixin 中的 create 方法的逻辑和 BookView、AuthorView 中的 post 方法的实现逻辑一致
class CreateModelMixin:
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
    
    # ...
"""

对代码再次进行封装:ListCreateAPIView

上述代码还能再进行封装,因为对每个表的增删改查都对应着相应的请求方法,且处理逻辑很类似,现在考虑把请求方法封装到一个类,然后让要完成增删改查功能的视图继承该类,这个抽取出来的单独的类一版称为 mixin 类
from rest_framework.generics import ListCreateAPIView

class AuthorViewModify2(ListCreateAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorViewSerializers

"""
ListCreateAPIView 源码:
class ListCreateAPIView(mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView):
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

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

由源码可知
ListCreateAPIView 类就是继承了 ListModelMixin、CreateModelMixin、GenericAPIView 三个类,并实现了 get 和 post 方法
所以再次修改 AuthorViewModify 类的代码


from rest_framework.generics import RetrieveUpdateDestroyAPIView
同理, RetrieveUpdateDestroyAPIView 类继承了 RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView
并且实现了相应的请求方法
其他的也可以从名字判断它的源码,如 RetrieveDestroyAPIView, RetrieveUpdateAPIView 等
RetrieveUpdateDestroyAPIView 源码如下:
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
                                   mixins.UpdateModelMixin,
                                   mixins.DestroyModelMixin,
                                   GenericAPIView):
    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 patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)

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

你可能感兴趣的:(python,django,restful,后端)