Django中如何为DjangoFilterBackend配置模型全字段过滤
Django DRF 实现模型全字段自动配置过滤的方案
filter_fields = ['__all__']配置不生效的核心原因有两点:
- DRF 视图层的
filter_fields参数原生不支持'__all__'取值,必须传入明确的字段名列表 - 代码存在拼写错误:正确参数名是
filter_fields,不是filter_fiels
不需要逐一枚举字段,以下两种方案均可实现全字段自动适配过滤,后续模型新增字段也无需修改过滤配置:
方案1:动态读取模型字段生成过滤列表(零额外配置,最轻量)
直接在视图内读取模型元数据,自动拉取所有需要支持过滤的字段名生成列表,效果和手动逐一枚举完全一致:
from rest_framework import viewsets from django_filters.rest_framework import DjangoFilterBackend from .models import Product from .serializers import ProductSerializer class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all() serializer_class = ProductSerializer filter_backends = [DjangoFilterBackend] # 自动读取模型非关联普通字段+主键id作为过滤字段 filter_fields = [ field.name for field in Product._meta.get_fields() if not field.is_relation and not field.many_to_many and not field.one_to_many or field.name == 'id' ]
如果需要支持关联字段过滤、或者要排除敏感字段,直接在列表推导式里加判断条件即可,比如要排除cost内部成本字段,就在判断条件里加and field.name != 'cost'。
方案2:使用django-filter原生的__all__配置(适合需要自定义过滤规则的场景)
django-filter 库本身的FilterSet类原生支持fields = '__all__'配置,只是不能直接写在视图的filter_fields参数里,需要先定义过滤集:
- 先编写对应模型的FilterSet类
from django_filters import rest_framework as filters from .models import Product class ProductFilter(filters.FilterSet): class Meta: model = Product fields = '__all__' # 原生支持全字段自动生成过滤规则
- 在视图中指定
filterset_class替换原来的filter_fields配置
class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all() serializer_class = ProductSerializer filter_backends = [DjangoFilterBackend] filterset_class = ProductFilter
注意:全字段开放过滤存在数据泄露风险,上线前务必确认所有开放过滤的字段都允许前端传入查询参数筛选,涉及内部敏感数据的字段一定要通过排除逻辑屏蔽。
内容的提问来源于stack exchange,提问作者amirabbas
相关产品推荐
相关产品推荐

