Django REST framework数据展示技巧:分页、过滤与搜刮的实用配置与实践 ...

打印 上一主题 下一主题

主题 827|帖子 827|积分 2481


系列文章目录

   

  • Django入门全攻略:从零搭建你的第一个Web项目
  • Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作
  • Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解
  • Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
  • 跨域问题与Django解决方案:深入解析跨域原理、哀求处理处罚与CSRF防护
  • Django视图层探索:GET/POST哀求处理处罚、参数转达与相应方式详解
  • Django路由与会话深度探索:静态、动态路由分发,以及Cookie与Session的奥秘
  • Django API开辟实战:前后端分离、Restful风格与DRF序列化器详解
  • Django REST framework序列化器详解:普通序列化器与模型序列化器的选择与运用
  • Django REST framework关联序列化器详解:掌握复杂关系的序列化与反序列化艺术
  • Django REST framework中GenericAPIView与混入扩展类详解
  • Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器
  • Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
  • Django REST framework数据展示技巧:分页、过滤与搜刮的实用配置与实践
  • 努力学习0.0ing…
  

  

前言

    在本篇博客中,我们将详细解析Django REST framework中分页、过滤和搜刮的定义、功能以及使用方法。我们不但会介绍如何进行基本的设置和使用,还会深入探讨如何进行全局配置和局部配置,以满足差别场景下的需求。
       分页功能 允许我们根据需求将数据分别为多个页面,确保用户在欣赏大量数据时不会感到杂乱或过载。过滤功能 则赋予了用户更精细地控制所看到数据的本领,通过预设条件或自定义查询,用户可以快速定位到所需信息。而搜刮功能 则进一步增强了这种本领,让用户能够通过关键词敏捷检索到相干数据。
  
一、分页

       试想一下,为什么我们几乎不在网页中一次性展示哀求获得的全部数据呢?
  

  • 如果这个数据量相当小,比如只有几十条,那么一般环境下无需担心,一股脑渲染到页面中就行。
  • 但如果这个数据量比较大,比如几百几千几万条,且一旦这种操作比较频仍,显然就会增长服务器负载,重要瓶颈是数据库。
    这里不谈如何实现高并发,只谈如何以轻量化的方式获取并展示数据。

一种有效的方式就是实现分页查询
将一次性获取全部数据的操作,分解为多次查询操作,每次操作只查询并展示一部分数据。其中每一次查询就是获取一页数据。
    结果如下:

  1. Django视图函数中实现分页

   django视图函数中实现分页结果:
  1. #views.py
  2. # 0.视图函数实现分页效果
  3. def index(request):
  4.     if request.method == 'POST':
  5.         return JsonResponse({"message":"POST测试列表分页"})
  6.         # return HttpResponse('{"message":"Hello POST"}',content_type='application/json')
  7.     elif request.method == 'GET':
  8.         list1 = ["张三","李四","王五","赵六","立秋","李琦","离奇",64,84,84,6,54,5,6,7]
  9.         # Paginator(列表数据,条数)
  10.         pagtor = Paginator(list1,3)
  11.         # 获取前端的查询参数:请求页数,页码
  12.         page = request.GET.get('page')
  13.         print(page)
  14.         data = pagtor.get_page(page)
  15.         print(data.object_list)
  16.         # return HttpResponse('{"message": data.object_list}',content_type='application/json')
  17.         return JsonResponse({"message":"测试GET列表分页",'data': data.object_list})
  18.         
复制代码
  注意:
JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)
JsonResponseHttpRespon的子类, 它重要和父类的区别在于:
  

  • 它的默认Content - Type被设置为: application/json
  • 第一个参数, data应该是一个字典范例, 当safe这个参数被设置为: False, 那data可以填入任何能被转换为JSON格式的对象, 比如list, tuple, set.
  • 默认的safe参数是True,如果你传入的data数据范例不是字典范例, 那么它就会抛出TypeError的异常
  2. DRF全局设置分页

   注意:必要修改Django的全局配置文件 settings.py
  1. # settings.py
  2. REST_FRAMEWORK = {
  3.     'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
  4.     'PAGE_SIZE': 3 #每页数据条数
  5. }
复制代码
  1. #views.py
  2. class IndexView(ListAPIView):
  3.     queryset = StudentModel.objects.all()
  4.     serializer_class = StudentSerializer
复制代码
3. DRF局部设置分页

   DRF自定义分页类对象并进行局部分页设置:
  1. #views.py
  2. #导入分页器类
  3. from rest_framework.pagination import PageNumberPagination
  4. # 局部分页配置  自定义分页器
  5. class MyPaginator(PageNumberPagination):
  6.     page_size = 2 # 每页数量
  7.     page_query_param = 'page' #查询参数:页码的参数名
  8.     page_size_query_param = 'page_size' #查询参数,每页数量的参数名
  9.     max_page_size = 10 #每页最大数量
  10. # http://localhost:8000/app01/indexview/?page=1&page_size=10
  11. # 1.DRF 分页
  12. class IndexView(ListAPIView):
  13.     queryset = StudentModel.objects.all()
  14.     serializer_class = StudentSerializer
  15.     pagination_class = MyPaginator
复制代码
4. 在APIView 中使用分页

   前面的使用内置分页的视图函数都必要继承 GenericAPIView、ListModelMixin(或者直接继承ListAPIView),如果在正常的APIview中,如何实现自定义分页呢?
    其实步调是一样的,只不过APIView中没有提供数据和方法的封装,全部的操作,必要手动完成,下面我们可以本身编写继承 APIView 的视图函数实现分页。
  1. class IndexView(APIView):
  2.     def get(self,request):
  3.         users = UserModel.objects.all()
  4.         
  5.         # 对数据集进行分页,自定义的分页器
  6.         # paginator = CommonPageNumberPagination()
  7.         #加载系统分页器
  8.         paginator = PageNumberPagination()
  9.         
  10.         #局部设置,配置对应page_size大小和对应参数key
  11.         paginator.page_size = 2
  12.         
  13.         # 获取分页过后的数据
  14.         qs = paginator.paginate_queryset(users, request, self)
  15.         
  16.         # 对数据进行序列化,多条数据需要添加 many=True
  17.         res = UserSer(qs, many=True)
  18.         
  19.                 # 返回的方式一,只返回分页后的结果
  20.         # return Response(res.data)
  21.         
  22.         # 返回方式二,自己配置返回的其他信息,例如上一页下一页
  23.         # return Response({
  24.         #     'count': books.count(),
  25.         #     'next': paginator.get_next_link(),
  26.         #     'previous': paginator.get_previous_link(),
  27.         #     'results': res.data
  28.         # })
  29.         
  30.         # 返回方式三,使用方法自动返回类似于方式二的内容
  31.         return paginator.get_paginated_response(res.data)
复制代码
二、过滤

   在 Django 中,django-filter 是一个强大的第三方应用,它提供了一种简朴、灵活且可定制的过滤器系统,允许开辟者轻松地对 Django 查询集进行过滤和排序。
    过滤器 允许用户根据特定的条件来筛选数据。在 Django 中,这通常意味着对查询集(QuerySet)进行过滤。
  1. django-filter的精准过滤

使用步调


  • 安装插件
该django-filter库包含一个DjangoFilterBackend类,该类支持针对REST框架的高度可自定义的字段筛选。
   要使用DjangoFilterBackend,请先安装django-filter
  1. pip install django-filter
复制代码


  • 注册APP
   添加'django_filters'到Django的INSTALLED_APPS:
  1. #settings.py
  2. INSTALLED_APPS = [
  3.     ...
  4.     'django_filters',
  5.     ...
  6. ]
复制代码


  • 配置过滤引擎
   将过滤器后端添加到全局设置中:
  1. REST_FRAMEWORK = {
  2.     'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
  3. }
复制代码
  全局配置 准确过滤
  1. import django_filters.rest_framework
  2. from rest_framework.generics import ListAPIView
  3. from app.models import StudentModel
  4. from app.serializer.studentSerializer import StudentSerializer
  5. # 1. 精确过滤
  6. class IndexFilterViews(ListAPIView):
  7.     queryset = StudentModel.objects.all()
  8.     serializer_class = StudentSerializer
  9.    
  10.     filterset_fields = ['name','gender']
  11. # 过滤
  12. # http://localhost:8000/app01/indexfilter/?name=张三
  13. # http://localhost:8000/app01/indexfilter/?name=张三&gender=1
复制代码
  局部配置 准确过滤
  1. import django_filters.rest_framework
  2. from rest_framework.generics import ListAPIView
  3. from app.models import StudentModel
  4. from app.serializer.studentSerializer import StudentSerializer
  5. # 局部配置 过滤
  6. from django_filters.rest_framework import DjangoFilterBackend
  7. # 1. 精确过滤
  8. class IndexFilterViews(ListAPIView):
  9.     queryset = StudentModel.objects.all()
  10.     serializer_class = StudentSerializer
  11.     filter_backends = [DjangoFilterBackend]
  12.     filterset_fields = ['name','gender']
  13. # 过滤
  14. # http://localhost:8000/app01/indexfilter/?name=张三
  15. # http://localhost:8000/app01/indexfilter/?name=张三&gender=1
复制代码
2. django-filter的模糊过滤

   默认的过滤器可以实现精准搜刮功能,但是对于有些字段或者数据,在开辟过程中必要实现模糊过滤,那么就必要进行过滤器的自定义实现,自定义一个高级过滤器,下面是 自定义过滤器
    模糊过滤
  1. # views_filter.py
  2. import django_filters.rest_framework
  3. from rest_framework.generics import ListAPIView
  4. from app.models import StudentModel
  5. from app.serializer.studentSerializer import StudentSerializer
  6. # 局部配置 过滤
  7. from django_filters.rest_framework import DjangoFilterBackend
  8. # 过滤器
  9. # 2. 模糊过滤
  10. class StudentFilter(django_filters.rest_framework.FilterSet):
  11.         """自定义过滤器类"""
  12.     name = django_filters.CharFilter(field_name='name', lookup_expr='contains')
  13.     # field_name 表示要过滤字段;lookup_expr 表示 过滤时要进行的操作,
  14.     # contains 表示 包含,用来进行模糊过滤
  15.    
  16.     maxgt_age = django_filters.NumberFilter(field_name='age', lookup_expr='gte')
  17.     minlt_age = django_filters.NumberFilter(field_name='age', lookup_expr='lte')
  18.     class Meta:
  19.         model = StudentModel
  20.         fields = ['name','maxgt_age','minlt_age'] #查询参数,与数据库无关
  21. class StudentVagueFilter(ListAPIView):
  22.     queryset = StudentModel.objects.all()
  23.     serializer_class = StudentSerializer
  24.     filter_backends = [DjangoFilterBackend] # 局部配置 过滤
  25.     filterset_class = StudentFilter # 指明过滤器类
  26. http://127.0.0.1:8000/app/students/?name=李
复制代码
3. rest_framework的SearchFilter

rest_framework 的 SearchFilter 是 Django REST framework 提供的一个过滤器后端类,专门用于在 API 视图中执行文本搜刮过滤。
SearchFilter 允许用户在查询字符串中通过特定的参数(默以为 search)来搜刮数据。这个过滤器基于数据库的全文搜刮功能(如果可用),在指定的字段上执行全文搜刮,并返回匹配指定搜刮词的结果。
   该搜刮引擎依靠于 rest_framework, 不必要安装额外的插件
  

  • 配置搜刮引擎
   将过滤器后端添加到全局设置中:
  1. REST_FRAMEWORK = {
  2.     'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter']
  3. }
复制代码
  局部配置 / 全局配置 搜刮:
  1. from rest_framework.generics import ListAPIView
  2. from app.models import StudentModel
  3. from app.serializer.studentSerializer import StudentSerializer
  4. # 局部配置 搜索
  5. #from rest_framework.filters import SearchFilter
  6. class IndexSearchView(ListAPIView):
  7.     queryset = StudentModel.objects.all()
  8.     serializer_class = StudentSerializer
  9.     # 局部配置 搜索
  10.     # filter_backends = [SearchFilter]
  11.    
  12.     search_fields = ['name']
  13.     # search_fields = ['^name'] 姓name的
  14.     # search_fields = ['=name'] 完全匹配,为name的
  15.     ordering_fields = ['age']
  16. http://127.0.0.1:8000/app/index/?search=张三
复制代码
  PS:可以通过在字符前面添加各种字符来限制搜刮举动search_fields:
  

  • '^'开始搜刮
  • '='完全匹配
  • '$'正则表达式搜刮
  
三、排序

使用Ordering-Filter实现排序

   将获取的数据按照肯定的字段要求顺序进行排序,其实在model 模型类中也可以定义ordering 字段实现,排序实现其实还是用到了过滤部分的功能
    实现排序要使用DRF 提供的OrderingFilter 实现
    设置 过滤器后端(两种方式)
  1. # 1.全局配置时--settings.py
  2. REST_FRAMEWORK = {
  3.     'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.OrderingFilter']
  4. }
  5. # 2.局部配置时---views_search.py
  6.   # 导入
  7.   from rest_framework.filters import SearchFilter,OrderingFilter
  8.   #视图 内部 (完整代码在下个代码块)
  9.   filter_backends = [filters.OrderingFilter]
复制代码
  views_search.py 完整代码如下:
  1. # views_search.py
  2. from rest_framework.generics import ListAPIView
  3. from app.models import StudentModel
  4. from app.serializer.studentSerializer import StudentSerializer
  5. # 局部配置(导包)  搜索
  6. from rest_framework.filters import SearchFilter,OrderingFilter
  7. class IndexSearchView(ListAPIView):
  8.     queryset = StudentModel.objects.all()
  9.     serializer_class = StudentSerializer
  10.    
  11.     # 局部配置时要设置filter_backends ,全局配置过就不用了
  12.     # filter_backends = [SearchFilter]
  13.     filter_backends = [SearchFilter,OrderingFilter]
  14.    
  15.     search_fields = ['name']
  16.     # search_fields = ['^name'] 以name开头的,姓 name的
  17.     # search_fields = ['=name'] 完全匹配,为 name的
  18.     ordering_fields = ['age']
  19. http://127.0.0.1:8000/app/indexsearch/?ordering=-age # 从大到小
  20. http://127.0.0.1:8000/app/indexsearch/?ordering=age # 从小到大
复制代码



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表