这是一个可重复使用的解决方案,使用自定义 Filter 和自定义 Field。
自定义的Field 重用了Django 的MultipleChoiceField,但替换了验证函数。
相反,它使用我们传递给构造函数的另一个 Field 类进行验证。
from django.forms.fields import MultipleChoiceField
class MultipleValueField(MultipleChoiceField):
def __init__(self, *args, field_class, **kwargs):
self.inner_field = field_class()
super().__init__(*args, **kwargs)
def valid_value(self, value):
return self.inner_field.validate(value)
def clean(self, values):
return values and [self.inner_field.clean(value) for value in values]
自定义Filter 使用MultipleValueField 并转发field_class 参数。
它还将lookup_expr 的默认值设置为in。
from django_filters.filters import Filter
class MultipleValueFilter(Filter):
field_class = MultipleValueField
def __init__(self, *args, field_class, **kwargs):
kwargs.setdefault('lookup_expr', 'in')
super().__init__(*args, field_class=field_class, **kwargs)
要使用此过滤器,只需使用适当的field_class 创建一个MultipleValueFilter。例如,要通过id 过滤City,我们可以使用IntegerField,如下所示:
from django.forms.fields import IntegerField
class CityFilterSet(FilterSet):
id = MultipleValueFilter(field_class=IntegerField)
name = filters.CharFilter(lookup_expr='icontains')
class Meta:
model = City
fields = ['name']