本系列文章中的上一篇文章: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 中的几个类: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)
""" 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) # ... """
上述代码还能再进行封装,因为对每个表的增删改查都对应着相应的请求方法,且处理逻辑很类似,现在考虑把请求方法封装到一个类,然后让要完成增删改查功能的视图继承该类,这个抽取出来的单独的类一版称为 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)
"""