你好,我在 python>=3.5 中的 FilterSet 派生类的实例化过程中发现了一个错误。 在 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())
当在 self.base_fields 上调用 copy.deepcopy() 时,它尝试选择字段并失败,因为选择的类型为 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
可以正常工作。
将其他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我对这个问题很感兴趣,但也不想炸毁这个线程。 听起来它可能超出了这个特定项目的范围。 我给你发邮件。
最有用的评论
对于那些仍然遇到这个问题的人,我是这样解决的: