DRF 过滤器组件
Contents
:::tip Django REST Framework. Filters :::
基本信息
源码
官方文档
DRF 过滤组件
DRF 搜索过滤组件
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('cars/', views.CarListAPIView.as_view()), # SearchFilter
]
views.py
# drf的SearchFilter
# 第一步: 搜索过滤
from rest_framework.filters import SearchFilter
class CarListAPIView(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer #自定义认证
# 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [SearchFilter]
# 第三步:SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=...
search_fields = ['name', 'price'] #筛选字段
# eg:/cars/?search=1,name和price中包含1的数据都会被查询出
DRF 排序过滤组件
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('cars2/', views.CarListAPIView2.as_view()), # OrderingFilter
]
views.py
# 第一步:drf的OrderingFilter - 排序过滤
from rest_framework.filters import OrderingFilter
class CarListAPIView2(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [OrderingFilter]
# 第三步:OrderingFilter过滤类依赖的过滤条件 => 接口:/cars/?ordering=...
ordering_fields = ['pk', 'price']
# eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序
自定义过滤器
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('cars3/', views.CarListAPIView3.as_view()), # 自定义fitler
]
filters.py
from . import models
# 自定义过滤器,接口:?limit=显示的条数
class LimitFilter:
def filter_queryset(self, request, queryset, view):
# 前台固定用 ?limit=... 传递过滤参数
limit = request.query_params.get('limit')
if limit:
limit = int(limit)
return queryset[:limit]
return queryset
views.py
# 自定义fitler
from .filters import LimitFilter
class CarListAPIView3(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [LimitFilter]
过滤器插件 django-filter
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('cars4/', views.CarListAPIView4.as_view()), # 插件django-filter
]
filters.py
# django-fitler插件:自定义过滤字段
from django_filters import filters
from django_filters.rest_framework.filterset import FilterSet
from django.db.models import Q
class CarFilterSet(FilterSet):
min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
top_category = django_filters.NumberFilter(method='top_category_filter')
def top_category_filter(self, queryset, name, value):
return queryset.filter(Q(category_id=value)|Q(category__parent_category_id=value)|Q(category__parent_category__parent_category_id=value))
class Meta:
model = models.Car
fields = ['brand', 'min_price', 'max_price']
# brand是model中存在的字段,一般都是可以用于分组的字段
# min_price、max_price是自定义字段,需要自己自定义过滤条件
views.py
# django-filter插件过滤器
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CarFilterSet
class CarListAPIView4(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [DjangoFilterBackend]
# django-filter过滤器插件使用
#filter_class = CarFilterSet
filterset_class = CarFilterSet # 旧版写作filter_class, 新版写作fitlerset_class
# 接口:?brand=...&min_price=...&max_price=...
# eg:?brand=宝马&min_price=5&max_price=10 => 5~10间的宝马牌汽车