Bonjour, j'ai détecté une erreur lors de l'instanciation de la classe dérivée de FilterSet en python>=3.5. En 3.4 tout fonctionne 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
Exemple de ma classe FilterSet. Les champs DateTimeFilter et CommaSeparatedCharFilter sont personnalisés :
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')
Salut @dangusev. La première réaction est que cela n'a pas de sens. Deux réflexions :
base_filters
doit être un OrderedDict
, pas un odict_items
. Est-ce que quelque chose remplace base_filters
?Désolé mon mauvais). J'ai beaucoup de code comme celui-ci :
category = ChoiceField(choices=CATEGORIES.items())
Lorsque copy.deepcopy() est appelé sur self.base_fields, il essaie de sélectionner des choix de champs et échoue, car les choix sont de type dict_items.
Pour ceux qui rencontrent encore ce problème, je l'ai résolu comme ceci:
list(CATEGORIES.items())
[Avec Python 3.85 et Django 3.1.1] De même, j'obtiens cette erreur dans l'une de mes vues de liste :
TypeError: cannot pickle 'dict_items' object
Rien dans le backtrace n'est dans mon code:
https://pastebin.com/S4xn8zpT
Il s'avère que le problème était d'ajouter une liste choices
à un CharField
dans mon modèle :
échoue:
record_request_status = models.CharField(max_length=4, null=True, choices=RECORD_REQUEST_STATUS)
fonctionne bien :
record_request_status = models.CharField(max_length=4, null=True)
RECORD_REQUEST_STATUS
est un dict :
with open('case-manager/src/json_fixtures/record_request_status.json') as json_file:
RECORD_REQUEST_STATUS = json.load(json_file).items()
L'attribution de cette même liste choices
à d'autres CharField
dans le modèle fonctionne très bien.
L'affectation d'autres listes choices
à record_request_status
échoue également.
cela marche:
record_request_status = models.CharField(max_length=4, null=True, choices=list(RECORD_REQUEST_STATUS))
Quelqu'un peut-il expliquer ce qui se passe?
@paulschreiber dans votre situation RECORD_REQUEST_STATUS
renvoie un dict_items
tapez au lieu d'une liste primitive ou Tuple .. dict_items
n'est pas un type connu pour cornichon à convertir il jette cette erreur . dict_items
a les bonnes méthodes implémentées pour compter comme un itérateur, donc la méthode list
fonctionne pour la convertir et donc les choix peuvent enfin accepter ce que vous transmettez.
Espérons que cela l'explique en bonne forme, cela fait quelques années que je n'ai pas regardé cela pour la dernière fois.
@ Ryanb58 Je ne comprends pas pourquoi cela échoue uniquement pour ce champ, mais fonctionne pour tous les autres champs de mes différents modèles. Dans chaque cas, je lis dans un fichier JSON qui est un dictionnaire.
@paulschreiber Je suis intéressé par le problème mais je ne veux pas non plus faire exploser ce fil. On dirait que cela pourrait être quelque chose en dehors de la portée de ce projet spécifique. Je vais vous envoyer un e-mail.
Commentaire le plus utile
Pour ceux qui rencontrent encore ce problème, je l'ai résolu comme ceci: