Django-filter: TypeError: невозможно обработать объекты odict_items в Python 3.5

Созданный на 14 нояб. 2016  ·  7Комментарии  ·  Источник: carltongibson/django-filter

Здравствуйте, я обнаружил ошибку во время создания класса, производного от FilterSet, в python> = 3.5. В 3.4 все работает нормально.

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

Пример моего класса FilterSet. Поля DateTimeFIlter и CommaSeparatedCharFilter настраиваются:

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

Самый полезный комментарий

Для тех, кто все еще сталкивается с этой проблемой, я решил ее так:

list(CATEGORIES.items())

Все 7 Комментарий

Привет @dangusev. Первоначальная реакция - то, что это не имеет смысла. Две мысли:

  • Набор тестов работает с python 3.5, проблема такого рода была бы решена.
  • base_filters должно быть OrderedDict , а не odict_items . Что-то отменяет base_filters ?

Извините, это моя ошибка). У меня много такого кода:

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

Когда copy.deepcopy () вызывается для self.base_fields, он пытается выбрать варианты полей и терпит неудачу, потому что варианты имеют тип dict_items.

Для тех, кто все еще сталкивается с этой проблемой, я решил ее так:

list(CATEGORIES.items())

[С Python 3.85 и Django 3.1.1] Точно так же я получаю эту ошибку в одном из моих списков:

TypeError: cannot pickle 'dict_items' object

В моем коде ничего в обратной трассировке нет:
https://pastebin.com/S4xn8zpT

Оказывается, проблема заключалась в добавлении списка choices к CharField в моей модели:

не удается:

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

работает нормально:

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

RECORD_REQUEST_STATUS - это изречение:

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

Назначение того же списка choices другим CharField s в модели работает нормально.
Назначение других списков choices для record_request_status также не выполняется.

это работает:

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

Может кто-нибудь объяснить, что происходит?

@paulschreiber в вашей ситуации RECORD_REQUEST_STATUS возвращает тип dict_items вместо простого списка или кортежа .. dict_items не является известным типом для преобразования pickle, поэтому он вызывает эту ошибку . dict_items есть соответствующие методы, реализованные для подсчета в качестве итератора, поэтому метод list работает при его преобразовании, и, таким образом, варианты выбора могут, наконец, принять то, что вы передаете.

Надеюсь, это объясняет это в хорошей форме, прошло несколько лет с тех пор, как я в последний раз смотрел на это.

@ Ryanb58 Я не понимаю, почему он не работает только для этого поля, но работает для всех других полей в моих различных моделях. В каждом случае я читаю файл JSON, являющийся словарем.

@paulschreiber Меня интересует проблема, но я не хочу взрывать эту ветку. Похоже, это может быть что-то за пределами этого конкретного проекта. Я отправлю тебе электронное письмо.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги