Mixin 类提供用于提供基本视图行为的操作。注意mixin类提供动作方法,而不是直接定义处理程序方法,例如 .get() 和 .post(), 这允许更灵活的行为组成。

Mixin 类可以从 rest_framework.mixins导入。

ListModelMixin

提供一个 .list(request, args, *kwargs) 方法,实现列出结果集。

如果查询集被填充了数据,则返回 200 OK 响应,将查询集的序列化表示作为响应的主体。相应数据可以任意分页。
打开**project\views.py**,修改ProjectView类中get方法,注释get方法,新增代码如下

  1. from rest_framework import mixins
  2. class ProjectView(mixins.ListModelMixin, GenericAPIView):
  3. # ...其余代码省略
  4. # # 查询数据
  5. # def get(self, request):
  6. # # 使用get_queryset()方法获取查询集对象,一般不会写成self.queryset
  7. # queryset = self.get_queryset()
  8. # # filter_queryset对查询对象进行过滤操作
  9. # queryset = self.filter_queryset(queryset)
  10. # # 使用paginate_queryset方法,进行分页操作
  11. # page = self.paginate_queryset(queryset)
  12. # if page is not None:
  13. # # 调用get_serializer,将page作为参数传给instance
  14. # serializer = self.get_serializer(instance=page, many=True)
  15. # # 分页必须调用get_paginated_response方法返回
  16. # return self.get_paginated_response(serializer.data)
  17. # # 使用get_serializer()方法获取序列化器类,一般不会写成self.serializer_class
  18. # serializer = self.get_serializer(instance=queryset, many=True)
  19. # return Response(serializer.data, status=status.HTTP_200_OK)
  20. def get(self, request, *args, **kwargs):
  21. return self.list(request, *args, **kwargs)

查询所有数据测试

image-20220317133514609.png

搜索测试

image-20220317133624247.png

排序测试,注意,如果前端输入-name,是倒序排序

image-20220317134142061.png

CreateModelMixin

提供 .create(request, args, *kwargs) 方法,实现创建和保存一个新的model实例。

如果创建了一个对象,这将返回一个 201 Created 响应,将该对象的序列化表示作为响应的主体。如果序列化的表示中包含名为 url的键,则响应的 Location 头将填充该值。

如果为创建对象提供的请求数据无效,将返回 400 Bad Request,其中错误详细信息作为响应的正文。
打开**project\views.py**,修改ProjectView类中post方法,注释post方法,新增代码如下

  1. class ProjectView(mixins.ListModelMixin, mixins.CreateModelMixin, GenericAPIView):
  2. # ...其余代码省略
  3. # def post(self, request):
  4. # # request.data:从request中获取请求数据
  5. # serializer_obj = self.get_serializer(data=request.data)
  6. # # 调用is_valid(raise_exception=True),校验失败时抛出异常
  7. # serializer_obj.is_valid(raise_exception=True)
  8. # serializer_obj.save()
  9. # return Response(serializer_obj.data, status=status.HTTP_201_CREATED)
  10. def post(self, request, *args, **kwargs):
  11. return self.create(request, *args, **kwargs)

创建数据测试

image-20220317134445969.png

RetrieveModelMixin

提供一个 .retrieve(request, args, *kwargs) 方法,实现返回响应中现有模型的实例。

如果可以检索对象,则返回 200 OK 响应,将该对象的序列化表示作为响应的主体。否则将返回 404 Not Found。

打开**project\views.py**,修改ProjectDetailView类中get方法,注释get方法,新增代码如下

  1. class ProjectDetailView(mixins.RetrieveModelMixin, GenericAPIView):
  2. queryset = Projects.objects.all()
  3. serializer_class = ProjectsModelSerializer
  4. # 查询单个数据
  5. # def get(self, request, pk):
  6. # # get_object可以获取模型对象,不需要传入前端传入的外键
  7. # project_obj = self.get_object()
  8. # serializer_obj = self.get_serializer(instance=project_obj)
  9. # return Response(serializer_obj.data, status=status.HTTP_200_OK)
  10. def get(self, request, *args, **kwargs):
  11. return self.retrieve(request, *args, **kwargs)

获取单个数据测试

image-20220317134520618.png

UpdateModelMixin

提供 .update(request, args, *kwargs) 方法,实现更新和保存现有模型实例。

同时还提供了一个 .partial_update(request, args, *kwargs) 方法,这个方法和 update 方法类似,但更新的所有字段都是可选的。这允许支持 HTTP PATCH 请求。

如果一个对象被更新,这将返回一个 200 OK 响应,将对象的序列化表示作为响应的主体。

如果为更新对象提供的请求数据无效,将返回一个 400 Bad Request 响应,错误详细信息作为响应的正文。

打开**project\views.py**,修改ProjectDetailView类中get方法,注释put方法,新增代码如下

  1. class ProjectDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, GenericAPIView):
  2. # ...其余代码省略
  3. # 更新数据
  4. # def put(self, request, pk):
  5. # project_obj = self.get_object()
  6. # serializer_obj = self.get_serializer(data=request.data, instance=project_obj)
  7. # # 调用is_valid(raise_exception=True),校验失败时抛出异常
  8. # serializer_obj.is_valid(raise_exception=True)
  9. # serializer_obj.save()
  10. # return JsonResponse(serializer_obj.data, status=status.HTTP_201_CREATED)
  11. def put(self, request, *args, **kwargs):
  12. return self.update(request, *args, **kwargs)

更新数据测试

image-20220317134600566.png

DestroyModelMixin

提供一个 .destroy(request, args, *kwargs) 方法,实现删除现有模型实例。

如果删除对象,则返回 204 No Content 响应,否则返回 404 Not Found。
打开**project\views.py**,修改ProjectDetailView类中delete方法,注释delete方法,新增代码如下

  1. class ProjectDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
  2. mixins.DestroyModelMixin, GenericAPIView):
  3. # ...其余代码省略
  4. # 删除数据
  5. # def delete(self, request, pk):
  6. # project_obj = self.get_object()
  7. # project_obj.delete()
  8. # return Response(data={"msg": "刪除成功"}, status=status.HTTP_204_NO_CONTENT)
  9. def delete(self, request, *args, **kwargs):
  10. return self.destroy(request, *args, **kwargs)

刪除数据测试

image-20220317134638954.png

ListCreateAPIView

用于读写端点以表示模型实例的集合。
提供一个 get 和 post 方法的处理程序。
扩展: GenericAPIView, ListModelMixin, CreateModelMixin
打开**project\views.py**,修改ProjectView类,继承ListCreateAPIView,删除get、post方法,代码如下

  1. from rest_framework.generics import ListCreateAPIView
  2. class ProjectView(ListCreateAPIView):
  3. # 一般需要指定queryset、serializer_class类属性
  4. queryset = Projects.objects.all()
  5. serializer_class = ProjectsModelSerializer
  6. # 指定过滤引擎
  7. filter_backends = [filters.SearchFilter, filters.OrderingFilter]
  8. # 过滤的字段
  9. search_fields = ['name', 'desc']
  10. # 指定字段默认升序排序
  11. # 如果在字段名称前添加“-”,代表改字段降序
  12. # 可以指定多个字段排序
  13. ordering_fields = ['name']

ok,我们继续用postman测试下。测试过程省略。

RetrieveUpdateDestroyAPIView

用于 读写删除 端点以表示 单个模型实例。
提供 get, put, patch 和 delete方法的处理程序。
扩展: GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
打开**project\views.py**,修改ProjectDetailView类,继承RetrieveUpdateDestroyAPIView,删除get、put、delete方法,代码如下

  1. from rest_framework.generics import RetrieveUpdateDestroyAPIView
  2. class ProjectDetailView(RetrieveUpdateDestroyAPIView):
  3. queryset = Projects.objects.all()
  4. serializer_class = ProjectsModelSerializer

ok,我们继续用postman测试下。测试过程省略。

使用ListCreateAPIView、RetrieveUpdateDestroyAPIView后的完整代码

天啦,现在代码被我们优化了只剩这么点了,我们来看下完整代码,代码量直接省去了一大半!

  1. from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
  2. from .models import Projects
  3. from .serializers import ProjectsModelSerializer
  4. from rest_framework import filters
  5. class ProjectView(ListCreateAPIView):
  6. # 一般需要指定queryset、serializer_class类属性
  7. queryset = Projects.objects.all()
  8. serializer_class = ProjectsModelSerializer
  9. # 指定过滤引擎
  10. filter_backends = [filters.SearchFilter, filters.OrderingFilter]
  11. # 过滤的字段
  12. search_fields = ['name', 'desc']
  13. ordering_fields = ['name']
  14. class ProjectDetailView(RetrieveUpdateDestroyAPIView):
  15. queryset = Projects.objects.all()
  16. serializer_class = ProjectsModelSerializer