Eu estava usando CSVWidget com CharFilter nos dias anteriores à 1.x, mas estou atualizando e essa combinação não funciona mais. Não consigo encontrar nenhum documento ou recomendação sobre o que mudar. Quero aceitar um único valor ou vários valores separados por vírgulas
Experimente algo como:
class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
pass
Eu mesmo passei algum tempo enfrentando esse problema, e acho que a solução @carltongibson definitivamente ajuda alguns problemas para mim.
Eu estava tentando fazer algo como:
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)
Usando DRF e um url de: ?id__in=a,b,c
No entanto, parece que usar widget=widgets.CSVWidget
realmente converte a lista como uma string de alguma forma?
Imprimir o valor do filtro resulta em "['a', 'b', 'c']"
o actual_filter também tem as aspas
Lookup(value="['a', 'b', 'c']", lookup_type='in')
De acordo com a recomendação fornecida, eu mudo as coisas para:
class UUIDInFilter(filters.BaseInFilter, filters.UUIDFilter):
pass
class BaseModelFilter(filters.FilterSet):
id = UUIDInFilter(name='id', lookup_expr='in')
E então eu fui capaz de usar ?id=3e543ed4-9b90-403d-8f40-048297a9ac31,6bf953eb-3ac3-4ea1-8ce5-9f84dd392246
para obter os resultados esperados.
A coisa "Listar como string" parece um bug ou pelo menos algumas alterações de documento, talvez? Não estou familiarizado com o funcionamento da funcionalidade subjacente. Talvez seja apenas usar erro =)
CSVWidget
está retornando corretamente uma lista de valores, entretanto CharField.clean()
está forçando a lista de volta a um valor de texto, portanto "['1', '2', '3']"
. Não é suficiente passar CSVWidget
para o filtro - o campo do formulário precisa ser sobrescrito para aceitar uma lista de valores.
A maneira mais fácil de obter o comportamento correto do campo é misturar o BaseCSVFilter
, já que ele constrói adequadamente um campo de formulário que aceita uma lista de valores.
Comentários muito úteis
CSVWidget
está retornando corretamente uma lista de valores, entretantoCharField.clean()
está forçando a lista de volta a um valor de texto, portanto"['1', '2', '3']"
. Não é suficiente passarCSVWidget
para o filtro - o campo do formulário precisa ser sobrescrito para aceitar uma lista de valores.A maneira mais fácil de obter o comportamento correto do campo é misturar o
BaseCSVFilter
, já que ele constrói adequadamente um campo de formulário que aceita uma lista de valores.