GenericAPIView继承APIView类,支持APIView视图的所有功能,还支持过滤、排序、分页等功能。

  • 指定queryset类属性,表示当前接口需要使用到的查询集(查询集对象)
  • 指定serializer_class类属性,表示当前接口需要使用到的序列化器类
  • 在对应的请求方法中,使用self.get_queryset()方法,获取查询集对象,建议不要直接使用self.queryset
  • 可以使用self.get_serializer()方法调用序列化器类,建议不要直接使用self.serializer_class
  • GenericAPIView提供get_object方法。其作用与下面的代码类似
    1. try:
    2. project_obj = Projects.objects.get(id=pk)
    3. except Projects.DoesNotExist:
    4. raise Http404

    过滤

    项目列表页通常有个搜索框,搜索框中我们可以输入内容进行搜索,这里说的过滤就是我们常说的搜索。我们根据name和desc进行搜索。

    导入filters

    1. from rest_framework import filters

    指定过滤引擎和过滤字段

    1. # 指定过滤引擎
    2. filter_backends = [filters.SearchFilter]
    3. # 过滤的字段
    4. search_fields = ['name', 'desc']

    完整代码

    修改project\views.py ```python from django.http import JsonResponse from rest_framework.generics import GenericAPIView from .models import Projects from .serializers import ProjectsModelSerializer from rest_framework.response import Response from rest_framework import status from rest_framework import filters

class ProjectView(GenericAPIView):

  1. # 一般需要指定queryset、serializer_class类属性
  2. queryset = Projects.objects.all()
  3. serializer_class = ProjectsModelSerializer
  4. # 指定过滤引擎
  5. filter_backends = [filters.SearchFilter]
  6. # 过滤的字段
  7. search_fields = ['name', 'desc']
  8. # 查询所有数据
  9. def get(self, request):
  10. # 使用get_queryset()方法获取查询集对象,一般不会写成self.queryset
  11. queryset = self.get_queryset()
  12. # filter_queryset对查询对象进行过滤操作
  13. queryset = self.filter_queryset(queryset)
  14. # 使用get_serializer()方法获取序列化器类,一般不会写成self.serializer_class
  15. serializer = self.get_serializer(instance=queryset, many=True)
  16. return Response(serializer.data, status=status.HTTP_200_OK)
  17. def post(self, request):
  18. # request.data:从request中获取请求数据
  19. serializer_obj = self.get_serializer(data=request.data)
  20. # 调用is_valid(raise_exception=True),校验失败时抛出异常
  21. serializer_obj.is_valid(raise_exception=True)
  22. serializer_obj.save()
  23. return Response(serializer_obj.data, status=status.HTTP_201_CREATED)

class ProjectDetailView(GenericAPIView): queryset = Projects.objects.all() serializer_class = ProjectsModelSerializer

  1. # 查询单个数据
  2. def get(self, request, pk):
  3. # get_object可以获取模型对象,不需要传入前端传入的外键
  4. project_obj = self.get_object()
  5. serializer_obj = self.get_serializer(instance=project_obj)
  6. return Response(serializer_obj.data, status=status.HTTP_200_OK)
  7. # 更新数据
  8. def put(self, request, pk):
  9. project_obj = self.get_object()
  10. serializer_obj = self.get_serializer(data=request.data, instance=project_obj)
  11. # 调用is_valid(raise_exception=True),校验失败时抛出异常
  12. serializer_obj.is_valid(raise_exception=True)
  13. serializer_obj.save()
  14. return JsonResponse(serializer_obj.data, status=status.HTTP_201_CREATED)
  15. # 删除数据
  16. def delete(self, request, pk):
  17. project_obj = self.get_object()
  18. project_obj.delete()
  19. return Response(data={"msg": "刪除成功"}, status=status.HTTP_204_NO_CONTENT)
  1. **增删改查测试过程略**<br />**postman 测试搜索,前端需要传?search=xxx**<br />![image-20220317104702227.png](https://cdn.nlark.com/yuque/0/2022/png/1700290/1651220990501-5b7120a5-038d-498d-894a-4ffe3b106907.png#clientId=u087a0f3c-be02-4&from=drop&id=ua8779c58&originHeight=781&originWidth=1142&originalType=binary&ratio=1&rotation=0&showTitle=false&size=68609&status=done&style=none&taskId=ub76ba259-0840-48cb-b0c6-cc24fb33441&title=)
  2. <a name="c360e994"></a>
  3. ## 排序
  4. <a name="82cad3f4"></a>
  5. ### 指定排序引擎和排序字段
  6. 打开`project\views.py`,修改代码
  7. ```python
  8. # 指定排序引擎
  9. filter_backends = [filters.SearchFilter, filters.OrderingFilter]
  10. # 指定字段默认升序排序
  11. # 如果在字段名称前添加“-”,代表改字段降序
  12. # 可以指定多个字段排序
  13. ordering_fields = ['name']
  14. # ordering_fields = ['name', 'desc']

postman 测试排序,前端需要传ordering=字段名
image-20220317110029865.png

分页

添加DEFAULT_PAGINATION_CLASS

打开caseplatform\setting.py文件,添加如下代码

  1. REST_FRAMEWORK = {
  2. DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
  3. # 指定每页显示多少
  4. 'PAGE_SIZE': 42
  5. }

打开project\views.py,修改代码

  1. class ProjectView(GenericAPIView):
  2. # 一般需要指定queryset、serializer_class类属性
  3. queryset = Projects.objects.all()
  4. serializer_class = ProjectsModelSerializer
  5. # 指定过滤引擎
  6. filter_backends = [filters.SearchFilter, filters.OrderingFilter]
  7. # 过滤的字段
  8. search_fields = ['name', 'desc']
  9. # 指定字段默认升序排序
  10. # 如果在字段名称前添加“-”,代表改字段降序
  11. # 可以指定多个字段排序
  12. ordering_fields = ['name']
  13. # ordering_fields = ['name', 'desc']
  14. # 查询所有数据
  15. def get(self, request):
  16. # 使用get_queryset()方法获取查询集对象,一般不会写成self.queryset
  17. queryset = self.get_queryset()
  18. # filter_queryset对查询对象进行过滤操作
  19. queryset = self.filter_queryset(queryset)
  20. # 使用paginate_queryset方法,进行分页操作
  21. page = self.paginate_queryset(queryset)
  22. if page is not None:
  23. # 调用get_serializer,将page作为参数传给instance
  24. serializer = self.get_serializer(instance=page, many=True)
  25. # 分页必须调用get_paginated_response方法返回
  26. return self.get_paginated_response(serializer.data)
  27. # 使用get_serializer()方法获取序列化器类,一般不会写成self.serializer_class
  28. serializer = self.get_serializer(instance=queryset, many=True)
  29. return Response(serializer.data, status=status.HTTP_200_OK)

注意,如果前端不传page,默认为第一页
使用postman测试
image-20220317114005512.png