Mixin 类提供用于提供基本视图行为的操作。注意mixin类提供动作方法,而不是直接定义处理程序方法,例如 .get() 和 .post(), 这允许更灵活的行为组成。
Mixin 类可以从 rest_framework.mixins导入。
ListModelMixin
提供一个 .list(request, args, *kwargs) 方法,实现列出结果集。
如果查询集被填充了数据,则返回 200 OK 响应,将查询集的序列化表示作为响应的主体。相应数据可以任意分页。
打开**project\views.py**,修改ProjectView类中get方法,注释get方法,新增代码如下
from rest_framework import mixinsclass ProjectView(mixins.ListModelMixin, GenericAPIView):# ...其余代码省略# # 查询数据# def get(self, request):# # 使用get_queryset()方法获取查询集对象,一般不会写成self.queryset# queryset = self.get_queryset()# # filter_queryset对查询对象进行过滤操作# queryset = self.filter_queryset(queryset)# # 使用paginate_queryset方法,进行分页操作# page = self.paginate_queryset(queryset)# if page is not None:# # 调用get_serializer,将page作为参数传给instance# serializer = self.get_serializer(instance=page, many=True)# # 分页必须调用get_paginated_response方法返回# return self.get_paginated_response(serializer.data)# # 使用get_serializer()方法获取序列化器类,一般不会写成self.serializer_class# serializer = self.get_serializer(instance=queryset, many=True)# return Response(serializer.data, status=status.HTTP_200_OK)def get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)
查询所有数据测试
搜索测试
排序测试,注意,如果前端输入-name,是倒序排序
CreateModelMixin
提供 .create(request, args, *kwargs) 方法,实现创建和保存一个新的model实例。
如果创建了一个对象,这将返回一个 201 Created 响应,将该对象的序列化表示作为响应的主体。如果序列化的表示中包含名为 url的键,则响应的 Location 头将填充该值。
如果为创建对象提供的请求数据无效,将返回 400 Bad Request,其中错误详细信息作为响应的正文。
打开**project\views.py**,修改ProjectView类中post方法,注释post方法,新增代码如下
class ProjectView(mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView):# ...其余代码省略# def post(self, request):# # request.data:从request中获取请求数据# serializer_obj = self.get_serializer(data=request.data)# # 调用is_valid(raise_exception=True),校验失败时抛出异常# serializer_obj.is_valid(raise_exception=True)# serializer_obj.save()# return Response(serializer_obj.data, status=status.HTTP_201_CREATED)def post(self, request, *args, **kwargs):return self.create(request, *args, **kwargs)
创建数据测试
RetrieveModelMixin
提供一个 .retrieve(request, args, *kwargs) 方法,实现返回响应中现有模型的实例。
如果可以检索对象,则返回 200 OK 响应,将该对象的序列化表示作为响应的主体。否则将返回 404 Not Found。
打开**project\views.py**,修改ProjectDetailView类中get方法,注释get方法,新增代码如下
class ProjectDetailView(mixins.RetrieveModelMixin, GenericAPIView):queryset = Projects.objects.all()serializer_class = ProjectsModelSerializer# 查询单个数据# def get(self, request, pk):# # get_object可以获取模型对象,不需要传入前端传入的外键# project_obj = self.get_object()# serializer_obj = self.get_serializer(instance=project_obj)# return Response(serializer_obj.data, status=status.HTTP_200_OK)def get(self, request, *args, **kwargs):return self.retrieve(request, *args, **kwargs)
获取单个数据测试
UpdateModelMixin
提供 .update(request, args, *kwargs) 方法,实现更新和保存现有模型实例。
同时还提供了一个 .partial_update(request, args, *kwargs) 方法,这个方法和 update 方法类似,但更新的所有字段都是可选的。这允许支持 HTTP PATCH 请求。
如果一个对象被更新,这将返回一个 200 OK 响应,将对象的序列化表示作为响应的主体。
如果为更新对象提供的请求数据无效,将返回一个 400 Bad Request 响应,错误详细信息作为响应的正文。
打开**project\views.py**,修改ProjectDetailView类中get方法,注释put方法,新增代码如下
class ProjectDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, GenericAPIView):# ...其余代码省略# 更新数据# def put(self, request, pk):# project_obj = self.get_object()# serializer_obj = self.get_serializer(data=request.data, instance=project_obj)# # 调用is_valid(raise_exception=True),校验失败时抛出异常# serializer_obj.is_valid(raise_exception=True)# serializer_obj.save()# return JsonResponse(serializer_obj.data, status=status.HTTP_201_CREATED)def put(self, request, *args, **kwargs):return self.update(request, *args, **kwargs)
更新数据测试
DestroyModelMixin
提供一个 .destroy(request, args, *kwargs) 方法,实现删除现有模型实例。
如果删除对象,则返回 204 No Content 响应,否则返回 404 Not Found。
打开**project\views.py**,修改ProjectDetailView类中delete方法,注释delete方法,新增代码如下
class ProjectDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,mixins.DestroyModelMixin, GenericAPIView):# ...其余代码省略# 删除数据# def delete(self, request, pk):# project_obj = self.get_object()# project_obj.delete()# return Response(data={"msg": "刪除成功"}, status=status.HTTP_204_NO_CONTENT)def delete(self, request, *args, **kwargs):return self.destroy(request, *args, **kwargs)
刪除数据测试
ListCreateAPIView
用于读写端点以表示模型实例的集合。
提供一个 get 和 post 方法的处理程序。
扩展: GenericAPIView, ListModelMixin, CreateModelMixin
打开**project\views.py**,修改ProjectView类,继承ListCreateAPIView,删除get、post方法,代码如下
from rest_framework.generics import ListCreateAPIViewclass ProjectView(ListCreateAPIView):# 一般需要指定queryset、serializer_class类属性queryset = Projects.objects.all()serializer_class = ProjectsModelSerializer# 指定过滤引擎filter_backends = [filters.SearchFilter, filters.OrderingFilter]# 过滤的字段search_fields = ['name', 'desc']# 指定字段默认升序排序# 如果在字段名称前添加“-”,代表改字段降序# 可以指定多个字段排序ordering_fields = ['name']
RetrieveUpdateDestroyAPIView
用于 读写删除 端点以表示 单个模型实例。
提供 get, put, patch 和 delete方法的处理程序。
扩展: GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
打开**project\views.py**,修改ProjectDetailView类,继承RetrieveUpdateDestroyAPIView,删除get、put、delete方法,代码如下
from rest_framework.generics import RetrieveUpdateDestroyAPIViewclass ProjectDetailView(RetrieveUpdateDestroyAPIView):queryset = Projects.objects.all()serializer_class = ProjectsModelSerializer
使用ListCreateAPIView、RetrieveUpdateDestroyAPIView后的完整代码
天啦,现在代码被我们优化了只剩这么点了,我们来看下完整代码,代码量直接省去了一大半!
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIViewfrom .models import Projectsfrom .serializers import ProjectsModelSerializerfrom rest_framework import filtersclass ProjectView(ListCreateAPIView):# 一般需要指定queryset、serializer_class类属性queryset = Projects.objects.all()serializer_class = ProjectsModelSerializer# 指定过滤引擎filter_backends = [filters.SearchFilter, filters.OrderingFilter]# 过滤的字段search_fields = ['name', 'desc']ordering_fields = ['name']class ProjectDetailView(RetrieveUpdateDestroyAPIView):queryset = Projects.objects.all()serializer_class = ProjectsModelSerializer
