如何为Django-filter添加包含、精确匹配及文本排除筛选功能?
Django-filter 扩展实现排除筛选(精确/包含匹配)
实现思路
重写FilterSet的filter_queryset方法,先处理常规的精确/包含筛选逻辑,再提取请求中带exclude_前缀的参数,将其解析为排除条件并批量应用到查询集,实现类似filter(...).exclude(...)的组合筛选效果。
自定义FilterSet类
import django_filters from .models import Table class TableFilter(django_filters.FilterSet): # 定义常规筛选字段,支持精确、包含匹配 col1 = django_filters.CharFilter(lookup_expr='contains') col2 = django_filters.CharFilter(lookup_expr='exact') col3 = django_filters.CharFilter(lookup_expr='contains') class Meta: model = Table fields = ['col1', 'col2', 'col3'] def filter_queryset(self, queryset): # 先执行常规筛选逻辑 queryset = super().filter_queryset(queryset) # 提取并处理排除参数 exclude_conditions = {} for param_key, param_value in self.data.items(): # 筛选带exclude_前缀且有有效值的参数 if param_key.startswith('exclude_') and param_value.strip(): # 移除前缀,得到字段+查找表达式(如col3__contains) lookup_key = param_key[8:] exclude_conditions[lookup_key] = param_value # 应用排除条件到查询集 if exclude_conditions: queryset = queryset.exclude(**exclude_conditions) return queryset
视图层集成(以DRF为例)
from rest_framework.generics import ListAPIView from .models import Table from .filters import TableFilter from .serializers import TableSerializer class TableListView(ListAPIView): queryset = Table.objects.all() serializer_class = TableSerializer filterset_class = TableFilter
筛选请求示例
以下是几种常见的筛选组合请求:
- 常规筛选+精确排除:
/tables/?col1__contains=text&col2=text2&exclude_col3=text3
效果等价于:Table.objects.filter(col1__contains='text', col2='text2').exclude(col3='text3') - 单独排除包含匹配:
/tables/?exclude_col1__contains=test
效果等价于:Table.objects.exclude(col1__contains='test') - 多条件排除:
/tables/?col2=foo&exclude_col3=bar&exclude_col1__contains=baz
效果等价于:Table.objects.filter(col2='foo').exclude(col3='bar', col1__contains='baz')
内容的提问来源于stack exchange,提问作者Loser Coder
相关产品推荐
相关产品推荐

