Список непонятных типов Python внутри JSON при рефакторинге в массив JSON - PullRequest
0 голосов
/ 17 декабря 2018

Я обычно знаю, как python работает с JSON (я думаю), но я столкнулся с тем, что не могу объяснить.

Я изначально использовал этот код в конечной точке API для предоставленияопции для выпадающих меню в приложении реагирования:

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 по-прежнему необходимо хешировать список втак же, так почему же он работает в первой форме, а не во второй?

Дополнительная информация:

Это в рамках остального django APIView, возвращение APIView возвращает объект Responseс этим объектом в нем.

Полный ТБ, хотя я не уверен, насколько он полезен:

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'

1 Ответ

0 голосов
/ 17 декабря 2018

Проблема в том, что у вас есть окружающий набор скобок - { ... }, а затем сразу внутри у вас есть квадратные скобки - [ ... ].Это означает, что Python интерпретирует вашу структуру как единый набор , к которому вы пытаетесь добавить один элемент, представляющий собой список, но списки не могут быть хешированы, поскольку они изменяемы.

IНе знаю, какой формат вы на самом деле хотите, но, возможно, вы хотели сбросить скобки?Тогда действительно у вас будет действительный список диктов.

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}
]

(или, возможно, вы хотели сохранить его как диктат, содержащий единственный элемент, представляющий собой список диктов - но тогда вам нужен ключ: data = {"data": [ ... ]}.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...