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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!