Django-filter: TypeError: no se pueden seleccionar objetos odict_items en Python 3.5

Creado en 14 nov. 2016  ·  7Comentarios  ·  Fuente: carltongibson/django-filter

Hola, detecté un error durante la creación de instancias de la clase derivada de FilterSet en python> = 3.5. En 3.4 todo funciona bien.

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

Ejemplo de mi clase FilterSet. Los campos DateTimeFIlter y CommaSeparatedCharFilter son 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')

Comentario más útil

Para aquellos que todavía se encuentran con este problema, lo resolví así:

list(CATEGORIES.items())

Todos 7 comentarios

Hola @dangusev. La reacción inicial es que no tiene sentido. Dos pensamientos:

  • El conjunto de pruebas se ejecuta en Python 3.5, este tipo de problema se habría detectado.
  • base_filters debe ser un OrderedDict , no un odict_items . ¿Hay algo que prevalezca sobre base_filters ?

Perdón, es mi culpa). Tengo mucho código como este:

category = ChoiceField(choices=CATEGORIES.items())

Cuando se llama a copy.deepcopy () en self.base_fields, intenta seleccionar opciones de campos y falla, porque las opciones tienen el tipo dict_items.

Para aquellos que todavía se encuentran con este problema, lo resolví así:

list(CATEGORIES.items())

[Con Python 3.85 y Django 3.1.1] De manera similar, recibo este error en una de mis vistas de lista:

TypeError: cannot pickle 'dict_items' object

Nada en el backtrace está en mi código:
https://pastebin.com/S4xn8zpT

Resulta que el problema era agregar una lista choices a una CharField en mi modelo:

falla:

record_request_status = models.CharField(max_length=4, null=True, choices=RECORD_REQUEST_STATUS)

funciona bien:

record_request_status = models.CharField(max_length=4, null=True)

RECORD_REQUEST_STATUS es un dict:

with open('case-manager/src/json_fixtures/record_request_status.json') as json_file:
        RECORD_REQUEST_STATUS = json.load(json_file).items()

Asignar esa misma lista choices a otros CharField s en el modelo funciona bien.
La asignación de otras listas choices a record_request_status también falla.

esto funciona:

record_request_status = models.CharField(max_length=4, null=True, choices=list(RECORD_REQUEST_STATUS))

¿Alguien puede explicar qué está pasando?

@paulschreiber en su situación RECORD_REQUEST_STATUS devuelve un tipo dict_items lugar de solo una Lista o Tupla primitiva .. dict_items no es un tipo conocido para que pickle lo convierta, por lo que arroja ese error . dict_items tiene los métodos adecuados implementados para contar como un iterador, por lo que el método list funciona para convertirlo y, por lo tanto, las opciones pueden finalmente aceptar lo que está pasando.

Con suerte, eso lo explica en buena forma, han pasado algunos años desde la última vez que miré esto.

@ Ryanb58 No entiendo por qué falla solo para este campo, pero funciona para todos los demás campos en mis diversos modelos. En cada caso, leo en un archivo JSON que es un diccionario.

@paulschreiber Estoy interesado en el problema pero tampoco quiero hacer estallar este hilo. Parece que podría ser algo fuera del alcance de este proyecto específico. Te enviaré un correo electrónico.

¿Fue útil esta página
0 / 5 - 0 calificaciones