【问题标题】:Python unhashable type list inside JSON when refactored into a JSON array重构为 JSON 数组时,JSON 中的 Python 不可散列类型列表
【发布时间】:2019-05-17 12:56:50
【问题描述】:

我一般都知道 python 如何处理 JSON(我认为),但我遇到了一些我无法解释的事情。

我最初在 api 端点中使用此代码来为 react 应用程序中的下拉菜单提供选项:

data = {
    "urgency_choices": URGENCY_CLASSES,
    "severity_choices": SEVERITY_CLASSES,
    "issue_classes": ISSUE_CLASSES,
    "flats": [(x.id, x.flat.name) for x in  OperationsFlat.objects.all()]
    }

然后我决定将其重构为提供一个“字段”的 JSON 数组,每个字段都有自己的选择键,以及它是否为必填字段:

data = {
    [
        {"name": "Urgency", "choices": URGENCY_CLASSES, "required": True},
        {"name": "Severity", "choices": SEVERITY_CLASSES, "required": True},
        {"name": "Issue Class", "choices": ISSUE_CLASSES, "required": True},
        {"name": "Flat", "choices": [(x.id, x.flat.name) for x in  OperationsFlat.objects.all()], "required": True}
    ]
}

错误是:

"name": "Flat", "choices": [(x.id, x.flat.name) for x in  OperationsFlat.objects.all()], "required": True}
TypeError: unhashable type: 'list'

在我看来,虽然列表的嵌套层次发生了变化,但python仍然需要以同样的方式对列表进行hash,那么为什么它在第一种形式中起作用,而在第二种形式中不起作用?

更多信息:

这是一个django rest框架APIView,APIView的返回返回一个Response对象,里面有这个对象。

完整的 TB,虽然我不确定它有多大用处:

Traceback (most recent call last):
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/django/core/handlers/base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/alexanderhalford/.pyenv/versions/xenia/lib/python3.5/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/alexanderhalford/work/nhuk/xenia/apps/operations/views.py", line 49, in get
    {"name": "Flat", "choices": {[(x.id, x.flat.name) for x in  OperationsFlat.objects.all()]}, "required": True}
TypeError: unhashable type: 'list'

【问题讨论】:

  • 在您重构的示例中,data 变量不是有效的 JSON。 data 变量是一个字典,其中的列表(我假设是 value)没有 key
  • 这是set,而不是dict ...和一组一个项目(list),因此您的问题...

标签: python arrays json django django-rest-framework


【解决方案1】:

问题是你有一组大括号 - { ... },然后你有方括号 - [ ... ]。这意味着 Python 将您的结构解释为单个 set,您尝试向其中添加单个项目,即列表 - 但列表不能被散列,因为它们是可变的。

我不知道你真正想要什么格式,但也许你打算完全去掉大括号?那么你确实会有一个有效的字典列表。

data = [
    {"name": "Urgency", "choices": URGENCY_CLASSES, "required": True},
    {"name": "Severity", "choices": SEVERITY_CLASSES, "required": True},
    {"name": "Issue Class", "choices": ISSUE_CLASSES, "required": True},
    {"name": "Flat", "choices": [(x.id, x.flat.name) for x in  OperationsFlat.objects.all()], "required": True}
]

(或者,也许,您打算将其保留为包含单个项目的 dict,该项目是一个 dicts 列表 - 但是您需要一个密钥:data = {"data": [ ... ]}。)

【讨论】:

  • 哎呀...我应该已经发现了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2018-12-26
  • 2019-01-07
  • 1970-01-01
  • 2015-07-05
相关资源
最近更新 更多