drf-过滤组件|分页组件|过滤器
群查接口各种筛选组件数据准备
models.py
| class Car(models.Model): |
| name = models.CharField(max_length=16, unique=True, verbose_name='车名') |
| price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格') |
| brand = models.CharField(max_length=16, verbose_name='品牌') |
| |
| class Meta: |
| db_table = 'api_car' |
| verbose_name = '汽车表' |
| verbose_name_plural = verbose_name |
| |
| def __str__(self): |
| return self.name |
admin.py
| admin.site.register(models.Car) |
serializers.py
| class CarModelSerializer(serializers.ModelSerializer): |
| class Meta: |
| model = models.Car |
| # 参与序列化的字段 |
| fields = ['name', 'price', 'brand'] |
views.py
| # Car的群查接口 |
| from rest_framework.generics import ListAPIView |
| |
| class CarListAPIView(ListAPIView): |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
urls.py
| url(r'^cars/$', views.CarListAPIView.as_view()), |
drf过滤组件
搜索过滤组件 | SearchFilter
| 使用步骤: |
| 1.导入搜索过滤器 SearchFilter |
| 2.局部配置 filter_backends = [SearchFilter] |
| 3.局部配置过滤类依赖的过滤条件(字段) search_fields = ['name', 'price'] 注意:依赖的过滤字段只能配置序列化类中fields里配置的字段 |
| 接口使用样式: |
| /cars/?search=... |
| |
案例:
views.py
| from rest_framework.generics import ListAPIView |
| |
| |
| from rest_framework.filters import SearchFilter |
| |
| class CarListAPIView(ListAPIView): |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| |
| filter_backends = [SearchFilter] |
| |
| |
| search_fields = ['name', 'price'] |
| |
排序过滤组件 | OrderingFilter
| 使用步骤: |
| 1.导入搜索过滤 OrderingFilter |
| 2.局部配置 filter_backends = [OrderingFilter] |
| 3.局部配置过滤类依赖的过滤条件(字段) ordering_fields = ['pk', 'price'] |
| 接口使用样式: |
| /cars/?ordering=... |
| |
案例:
views.py
| from rest_framework.generics import ListAPIView |
| |
| |
| from rest_framework.filters import OrderingFilter |
| |
| class CarListAPIView(ListAPIView): |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| |
| filter_backends = [OrderingFilter] |
| |
| |
| ordering_fields = ['pk', 'price'] |
| |
drf分页组件
自定义分页组件:
| 1.pagination.py中自定义分页类(基础分页类/偏移分页类/游标分页类) |
| 2.视图类中配置自定义的分页类: pagination_class = 自定义分页类 |
基础分页组件
| from rest_framework.pagination import PageNumberPagination |
| |
| class MyPageNumberPagination(PageNumberPagination): |
| |
| page_query_param = 'page' |
| |
| page_size = 3 |
| |
| page_size_query_param = 'page_size' |
| |
| max_page_size = 5 |
views.py
| from rest_framework.generics import ListAPIView |
| |
| class CarListAPIView(ListAPIView): |
| # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题 |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可 |
| pagination_class = pagenations.MyPageNumberPagination |
| |
偏移分页组件
| from rest_framework.pagination import LimitOffsetPagination |
| class MyLimitOffsetPagination(LimitOffsetPagination): |
| |
| limit_query_param = 'limit' |
| offset_query_param = 'offset' |
| |
| |
| default_limit = 3 |
| |
| |
| max_limit = 5 |
| |
| |
| |
views.py
| from rest_framework.generics import ListAPIView |
| |
| class CarListAPIView(ListAPIView): |
| # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题 |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可 |
| pagination_class = pagenations.MyLimitOffsetPagination |
| |
游标分页组件
| # 注:必须基于排序规则下进行分页 |
| # 1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering |
| # 1)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序 |
| from rest_framework.pagination import CursorPagination |
| class MyCursorPagination(CursorPagination): |
| cursor_query_param = 'cursor' |
| page_size = 3 |
| page_size_query_param = 'page_size' |
| max_page_size = 5 |
| ordering = '-pk' |
views.py
| from rest_framework.generics import ListAPIView |
| |
| class CarListAPIView(ListAPIView): |
| # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题 |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可 |
| pagination_class = pagenations.MyCursorPagination |
| |
自定义过滤类
源码:
| class GenericAPIView(views.APIView): |
| ... |
| |
| filter_backends = api_settings.DEFAULT_FILTER_BACKENDS |
| ... |
| |
| def filter_queryset(self, queryset): |
| |
| for backend in list(self.filter_backends): |
| |
| |
| queryset = backend().filter_queryset(self.request, queryset, self) |
| return queryset |
使用:
filters.py
| class LimitFilter: |
| |
| def filter_queryset(self, request, queryset, view): |
| |
| limit_mun = request.query_params.get('limit') |
| if limit_mun: |
| limit_mun = int(limit_mun) |
| |
| return queryset[:limit_mun] |
| return queryset |
views.py
| from rest_framework.generics import ListAPIView |
| |
| class CarListAPIView(ListAPIView): |
| # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题 |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS) |
| filter_backends = [LimitFilter] |
| |
过滤器插件:django-filter
安装
| >: pip3 install django-filter |
过滤条件层:自定义api/filters.py
| from django_filters.rest_framework.filterset import FilterSet |
| from . import models |
| from django_filters import filters |
| |
| class CarFilterSet(FilterSet): |
| |
| max_price = filters.NumberFilter( |
| field_name='price', |
| lookup_expr='gte', |
| ) |
| min_price = filters.NumberFilter( |
| field_name='price', |
| lookup_expr='lte', |
| ) |
| class Meta: |
| model = models.Car |
| fields = ['brand', 'min_price', 'max_price'] |
| |
| |
视图层:views.py
| |
| from django_filters.rest_framework import DjangoFilterBackend |
| from .filters import CarFilterSet |
| |
| class CarListAPIView(ListAPIView): |
| queryset = models.Car.objects.all() |
| serializer_class = serializers.CarModelSerializer |
| |
| |
| filter_backends = [DjangoFilterBackend] |
| |
| |
| filter_class = CarFilterSet |
| |
| |
| |
转自 https://www.cnblogs.com/demiao/p/11986303.html
https://blog.csdn.net/T_I_A_N_/article/details/99625478
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)