Django-filter: TypeError: não é possível selecionar objetos odict_items em Python 3.5

Criado em 14 nov. 2016  ·  7Comentários  ·  Fonte: carltongibson/django-filter

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')

Comentários muito úteis

Para aqueles que ainda enfrentam esse problema, resolvi assim:

list(CATEGORIES.items())

Todos 7 comentários

Olá @dangusev. A reação inicial é que não faz sentido. Dois pensamentos:

  • O conjunto de testes é executado no python 3.5, esse tipo de problema teria sido detectado.
  • 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ê.

Esta página foi útil?
0 / 5 - 0 avaliações