Olá, recebi um erro durante a instanciação da classe derivada de FilterSet em python> = 3.5. No 3.4 tudo funciona bem.
File "/home/dan/venvs/notes3.5/lib/python3.5/site-packages/django_filters/filterset.py" in __init__
291. self.filters = copy.deepcopy(self.base_filters)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in deepcopy
182. y = _reconstruct(x, rv, 1, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in _reconstruct
320. value = deepcopy(value, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in deepcopy
182. y = _reconstruct(x, rv, 1, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in _reconstruct
297. state = deepcopy(state, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in deepcopy
155. y = copier(x, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in _deepcopy_dict
243. y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in deepcopy
155. y = copier(x, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in _deepcopy_dict
243. y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/home/dan/venvs/notes3.5/lib/python3.5/copy.py" in deepcopy
174. rv = reductor(4)
Exception Type: TypeError at /notes/
Exception Value: can't pickle odict_items objects
Exemplo de minha classe FilterSet. Os campos DateTimeFIlter e CommaSeparatedCharFilter são personalizados:
class NoteListFilterset(django_filters.FilterSet):
strict = STRICTNESS.RAISE_VALIDATION_ERROR
keywords = CommaSeparatedCharFilter(name='keyword', lookup_expr='in')
datetime_from = DateTimeFilter(name='datetime', lookup_expr='gte')
datetime_to = DateTimeFilter(name='datetime', lookup_expr='lte')
get_hidden = django_filters.MethodFilter(method='filter_by_get_hidden')
Olá @dangusev. A reação inicial é que não faz sentido. Dois pensamentos:
base_filters
deve ser OrderedDict
, não odict_items
. Algo está substituindo base_filters
?Desculpe, minha culpa). Eu tenho muitos códigos como este:
category = ChoiceField(choices=CATEGORIES.items())
Quando copy.deepcopy () está sendo chamado em self.base_fields, ele tenta selecionar opções de campos e falha, porque as opções têm tipo dict_items.
Para aqueles que ainda enfrentam esse problema, resolvi assim:
list(CATEGORIES.items())
[Com Python 3.85 e Django 3.1.1] Da mesma forma, estou recebendo este erro em uma das minhas visualizações de lista:
TypeError: cannot pickle 'dict_items' object
Nada no backtrace está em meu código:
https://pastebin.com/S4xn8zpT
Acontece que o problema era adicionar uma lista choices
a uma CharField
no meu modelo:
falha:
record_request_status = models.CharField(max_length=4, null=True, choices=RECORD_REQUEST_STATUS)
funciona bem:
record_request_status = models.CharField(max_length=4, null=True)
RECORD_REQUEST_STATUS
é um ditado:
with open('case-manager/src/json_fixtures/record_request_status.json') as json_file:
RECORD_REQUEST_STATUS = json.load(json_file).items()
Atribuir a mesma lista choices
a outros CharField
s no modelo funciona bem.
Atribuir outras choices
listas a record_request_status
também falha.
isso funciona:
record_request_status = models.CharField(max_length=4, null=True, choices=list(RECORD_REQUEST_STATUS))
Alguém pode explicar o que está acontecendo?
@paulschreiber em sua situação RECORD_REQUEST_STATUS
retorna um tipo dict_items
vez de apenas uma Lista ou Tupla primitiva .. dict_items
não é um tipo conhecido de pickle para converter, por isso gera esse erro . dict_items
tem os métodos apropriados implementados para contar como um iterador, então o método list
funciona na conversão e, portanto, as escolhas podem finalmente aceitar o que você está passando.
Esperançosamente, isso explica em boa forma, já se passaram alguns anos desde a última vez que olhei para isso.
@ Ryanb58 Não entendo por que falha apenas neste campo, mas funciona em todos os outros campos em meus vários modelos. Em cada caso, estou lendo um arquivo JSON que é um dicionário.
@paulschreiber Estou interessado no problema, mas também não quero explodir este tópico. Parece que pode ser algo fora do escopo deste projeto específico. Vou mandar um e-mail para você.
Comentários muito úteis
Para aqueles que ainda enfrentam esse problema, resolvi assim: