DjangoFilterBackend 真正强大的地方是:
- 自定义 lookup
- 支持
icontains - 支持
in - 支持区间
- 支持时间范围
- 支持组合查询
企业项目里一般都会配合:
python
django-filter
和:
python
FilterSet
来实现高级搜索。
一、安装
bash
pip install django-filter
二、settings.py
python
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend'
]
}
三、基础 FilterSet
模型:
python
class User(models.Model):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=20)
status = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
四、模糊搜索(icontains)
python
import django_filters
class UserFilter(django_filters.FilterSet):
name = django_filters.CharFilter(
field_name='name',
lookup_expr='icontains'
)
class Meta:
model = User
fields = ['name']
请求
python
GET /api/users/?name=tom
SQL:
sql
WHERE name LIKE '%tom%'
五、IN 查询(最常用)
例如:
python
?id__in=1,2,3
写法
python
class NumberInFilter(django_filters.BaseInFilter,
django_filters.NumberFilter):
pass
python
class UserFilter(django_filters.FilterSet):
id__in = NumberInFilter(
field_name='id',
lookup_expr='in'
)
class Meta:
model = User
fields = []
请求
python
GET /api/users/?id__in=1,2,3
SQL:
sql
WHERE id IN (1,2,3)
六、多字段模糊搜索(企业最常见)
例如:
- name
- phone
都支持模糊。
python
class UserFilter(django_filters.FilterSet):
name = django_filters.CharFilter(
lookup_expr='icontains'
)
phone = django_filters.CharFilter(
lookup_expr='icontains'
)
class Meta:
model = User
fields = ['name', 'phone']
七、时间区间搜索
python
created_at_after = django_filters.DateTimeFilter(
field_name='created_at',
lookup_expr='gte'
)
created_at_before = django_filters.DateTimeFilter(
field_name='created_at',
lookup_expr='lte'
)
请求:
python
GET /api/users/?created_at_after=2025-01-01
八、完整企业版 FilterSet(推荐)
python
import django_filters
class NumberInFilter(django_filters.BaseInFilter,
django_filters.NumberFilter):
pass
class UserFilter(django_filters.FilterSet):
# 模糊搜索
name = django_filters.CharFilter(
lookup_expr='icontains'
)
phone = django_filters.CharFilter(
lookup_expr='icontains'
)
# IN 查询
id__in = NumberInFilter(
field_name='id',
lookup_expr='in'
)
# 精确查询
status = django_filters.NumberFilter()
# 时间范围
created_at_after = django_filters.DateTimeFilter(
field_name='created_at',
lookup_expr='gte'
)
created_at_before = django_filters.DateTimeFilter(
field_name='created_at',
lookup_expr='lte'
)
class Meta:
model = User
fields = []
九、ViewSet 配置
python
from django_filters.rest_framework import DjangoFilterBackend
class UserViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [DjangoFilterBackend]
filterset_class = UserFilter
十、支持的请求示例
模糊搜索
python
GET /api/users/?name=tom
IN 查询
python
GET /api/users/?id__in=1,2,3
多条件
python
GET /api/users/?name=tom&status=1
时间范围
python
GET /api/users/?created_at_after=2025-01-01
十一、企业项目最推荐方式
企业里通常:
python
filter_backends = [
DjangoFilterBackend,
OrderingFilter,
]
不要用:
python
SearchFilter
因为:
- SearchFilter 太弱
- 不好维护
- 不支持复杂条件
真正企业级都是:
python
FilterSet + lookup_expr
十二、更高级:自定义 OR 搜索
例如:
python
keyword=tom
同时搜索:
- name
- phone
这个要自定义方法:
python
from django.db.models import Q
class UserFilter(django_filters.FilterSet):
keyword = django_filters.CharFilter(method='filter_keyword')
def filter_keyword(self, queryset, name, value):
return queryset.filter(
Q(name__icontains=value) |
Q(phone__icontains=value)
)
class Meta:
model = User
fields = []
请求:
python
GET /api/users/?keyword=tom
这个是企业里最常见的"关键词搜索"。