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')
Hola @dangusev. La reacción inicial es que no tiene sentido. Dos pensamientos:
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.
Comentario más útil
Para aquellos que todavía se encuentran con este problema, lo resolví así: