Здравствуйте, я обнаружил ошибку во время создания класса, производного от 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')
Привет @dangusev. Первоначальная реакция - то, что это не имеет смысла. Две мысли:
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 Меня интересует проблема, но я не хочу взрывать эту ветку. Похоже, это может быть что-то за пределами этого конкретного проекта. Я отправлю тебе электронное письмо.
Самый полезный комментарий
Для тех, кто все еще сталкивается с этой проблемой, я решил ее так: