Django REST Framework中多值同列过滤返回空结果的解决方法
解决Django REST Framework中多值Website筛选的问题
你遇到的问题是因为默认的CharFilter不支持多值筛选,而你自定义的过滤方法虽然思路正确,但没处理好边界情况(比如参数中的空格),其实还有更简洁的内置方案可以直接用。下面给你两种可行的解决办法:
方法一:使用内置的InCharFilter(推荐)
Django Filter库提供了专门用于__in查询的过滤器,InCharFilter可以自动处理逗号分隔的多值参数,甚至支持多参数传递(比如?website=FAO&website=CD),不需要自己写自定义方法,非常省心。
修改你的op_filter类如下:
from django_filters import FilterSet, InCharFilter class op_filter(FilterSet): # 替换原来的CharFilter为InCharFilter,指定lookup_expr为'in' website = InCharFilter(field_name='website', lookup_expr='in') # 其他字段定义保持不变... class Meta: model = Op fields = ['website', ...] # 保留其他字段
这样修改后,不管你用https://...../op/?website=FAO,CD,BD还是https://...../op/?website=FAO&website=CD&website=BD的请求方式,都能正确筛选出符合条件的行。
方法二:修复自定义的过滤方法
如果你更倾向于自己实现过滤逻辑,那需要优化你的filter_by_website方法,主要处理两个问题:
- 拆分后的网站名称可能带有前后空格(比如用户输入
FAO, CD, BD),导致和数据库中的值不匹配 - 过滤掉拆分后可能出现的空字符串(比如用户输入
,FAO,,BD这种不规范的参数)
修改后的方法代码:
def filter_by_website(self, queryset, name, value): # 拆分字符串,逐个去除前后空格,同时过滤空字符串 website_names = [site.strip() for site in value.split(',') if site.strip()] # 直接用列表传入__in查询,不需要转成集合(集合会打乱顺序,但不影响筛选结果) return queryset.filter(website__in=website_names)
原来的代码中用set()其实没必要,因为__in接受列表、元组或者集合,不过列表更直观。处理空格和空字符串后,就能正确匹配数据库中的website值了。
额外检查
确保你的项目中已经正确配置了Django Filter:
- 已经安装了
django-filter包(pip install django-filter) - 在
settings.py的INSTALLED_APPS中添加了'django_filters' - ViewSet中已经正确设置了
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter](你已经做到了这一点)
内容的提问来源于stack exchange,提问作者Talib Daryabi
相关产品推荐
相关产品推荐

