Django-filter: 类型错误:无法在 python 3.5 中腌制 odict_items 对象

创建于 2016-11-14  ·  7评论  ·  资料来源: carltongibson/django-filter

你好,我在 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')

最有用的评论

对于那些仍然遇到这个问题的人,我是这样解决的:

list(CATEGORIES.items())

所有7条评论

嗨@dangusev。 最初的反应是它没有意义。 两个想法:

  • 测试套件是针对 python 3.5 运行的,这种问题会被发现。
  • 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我对这个问题很感兴趣,但也不想炸毁这个线程。 听起来它可能超出了这个特定项目的范围。 我给你发邮件。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

maxtepkeev picture maxtepkeev  ·  9评论

loganknecht picture loganknecht  ·  10评论

stantond picture stantond  ·  11评论

cancan101 picture cancan101  ·  8评论

earshinov picture earshinov  ·  14评论