我在 1.x 版之前使用了带有 CharFilter 的 CSVWidget,但我正在升级并且该组合不再有效。 我找不到关于切换到什么的任何文档或建议。 我想接受以逗号分隔的单个值或多个值
尝试类似:
class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
pass
我花了一些时间自己遇到了这个问题,我认为
我试图做这样的事情:
class TestListFilter(Filter):
field_class = forms.CharField
def filter(self, qs, value):
actual_filter = fields.Lookup(value, 'in')
from pprint import pprint
pprint(value)
pprint(actual_filter)
return qs
class BaseModelFilter(filters.FilterSet):
id__in = TestListFilter(name='id', lookup_expr='in', widget=widgets.CSVWidget)
使用 DRF 和以下网址: ?id__in=a,b,c
然而,似乎使用widget=widgets.CSVWidget
实际上以某种方式将列表转换为字符串?
在"['a', 'b', 'c']"
打印过滤器的值
actual_filter 也有引号Lookup(value="['a', 'b', 'c']", lookup_type='in')
根据提供的建议,我将事情改为:
class UUIDInFilter(filters.BaseInFilter, filters.UUIDFilter):
pass
class BaseModelFilter(filters.FilterSet):
id = UUIDInFilter(name='id', lookup_expr='in')
然后我就可以使用?id=3e543ed4-9b90-403d-8f40-048297a9ac31,6bf953eb-3ac3-4ea1-8ce5-9f84dd392246
以获得预期的结果。
“作为字符串列表”的东西看起来像是一个错误或者至少是一些文档更改? 不过,我对底层功能的工作原理非常陌生。 也许这只是使用错误 =)
CSVWidget
正确返回了一个值列表,但是CharField.clean()
将列表强制转换回文本值,因此"['1', '2', '3']"
。 将CSVWidget
传递给过滤器是不够的 - 需要覆盖表单字段以接受值列表。
获得正确字段行为的最简单方法是混合BaseCSVFilter
,因为它正确构造了一个接受值列表的表单字段。
最有用的评论
CSVWidget
正确返回了一个值列表,但是CharField.clean()
将列表强制转换回文本值,因此"['1', '2', '3']"
。 将CSVWidget
传递给过滤器是不够的 - 需要覆盖表单字段以接受值列表。获得正确字段行为的最简单方法是混合
BaseCSVFilter
,因为它正确构造了一个接受值列表的表单字段。