Django-filter: TypeError: odict_items-Objekte in Python 3.5 können nicht eingelegt werden

Erstellt am 14. Nov. 2016  ·  7Kommentare  ·  Quelle: carltongibson/django-filter

Hallo, ich habe einen Fehler bei der Instanziierung der von FilterSet abgeleiteten Klasse in Python>=3.5 festgestellt. In 3.4 funktioniert alles ok.

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

Beispiel für meine FilterSet-Klasse. Die Felder DateTimeFIlter und CommaSeparatedCharFilter sind benutzerdefiniert:

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

Hilfreichster Kommentar

Für diejenigen, die immer noch auf dieses Problem stoßen, habe ich es wie folgt gelöst:

list(CATEGORIES.items())

Alle 7 Kommentare

Hallo @dangusev. Die erste Reaktion ist, dass es keinen Sinn macht. Zwei Gedanken:

  • Die Testsuite wird gegen Python 3.5 ausgeführt, diese Art von Problem wäre behoben worden.
  • base_filters sollte ein OrderedDict , kein odict_items . Überschreibt etwas base_filters ?

Es tut mir leid). Ich habe viel Code wie diesen:

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

Wenn copy.deepcopy() auf self.base_fields aufgerufen wird, versucht es, Auswahlen von Feldern zu picken und schlägt fehl, weil Auswahlen vom Typ dict_items sind.

Für diejenigen, die immer noch auf dieses Problem stoßen, habe ich es wie folgt gelöst:

list(CATEGORIES.items())

[Mit Python 3.85 und Django 3.1.1] In ähnlicher Weise erhalte ich diesen Fehler in einer meiner Listenansichten:

TypeError: cannot pickle 'dict_items' object

Nichts im Backtrace ist in meinem Code:
https://pastebin.com/S4xn8zpT

Es stellte sich heraus, dass das Problem darin bestand, eine choices Liste zu einem CharField in meinem Modell hinzuzufügen:

schlägt fehl:

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

funktioniert gut:

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

RECORD_REQUEST_STATUS ist ein Diktat:

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

Das Zuweisen derselben choices Liste zu anderen CharField s im Modell funktioniert einwandfrei.
Das Zuweisen anderer choices Listen zu record_request_status schlägt ebenfalls fehl.

das funktioniert:

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

Kann jemand erklären, was los ist?

@paulschreiber in Ihrer Situation RECORD_REQUEST_STATUS kehrt ein dict_items geben , anstatt nur eine primitive Liste oder Tuple .. dict_items ist kein bekannter Typ für Beize zu konvertieren , so dass es diesen Fehler wirft . dict_items hat die richtigen Methoden implementiert, um als Iterator zu zählen, so dass die Methode list bei der Konvertierung funktioniert und somit die Auswahl endlich akzeptieren kann, was Sie übergeben.

Hoffentlich erklärt das es in guter Form, es ist ein paar Jahre her, seit ich mir das das letzte Mal angeschaut habe.

@ Ryanb58 Ich verstehe nicht, warum es nur für dieses Feld fehlschlägt, aber für alle anderen Felder in meinen verschiedenen Modellen funktioniert. In jedem Fall lese ich eine JSON-Datei ein, die ein Wörterbuch ist.

@paulschreiber Ich interessiere mich für das Problem, möchte diesen Thread aber auch nicht sprengen. Klingt so, als ob es etwas außerhalb des Rahmens dieses spezifischen Projekts sein könnte. Ich schreibe dir eine E-Mail.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen