Django - Объект типа Decimal не сериализуем в формате JSON и преобразуется в данные модели в представлениях - PullRequest
0 голосов
/ 13 сентября 2018
rows = fetchall()
resultList = []
resultModel = []
resultDict = []
for row in rows:
    resultModel.append(ResultModel(*row)) # Object of type ResultModel is not JSON serializable
    resultList.append(list(row)) # Rows returned by pyodbc are not JSON serializable
    resultDict.append(dict(zip(columns, row))) # Object of type Decimal is not JSON serializable

Мне нужно получить json-версию данных в представлении. Для этого я пытаюсь получить дамп JSON данных. Использование json.dumps(resultDict) выдает ошибку.

Ошибки, пробующие разные результаты из модели, закомментированы для справки. Параметр dict(zip()) является наиболее близким к тому, что я хочу, resultDict дает мне пару JSON (ключ, значение), которую я могу использовать. Но это дает мне ошибку в результирующих данных, которые включают в себя 'DecimalField'. Есть ли способ иметь десятичные разряды без ошибок в данных, возвращаемых обратно? Кажется, это было бы просто, что Django поддерживал, поэтому я не уверен, что что-то упустил!

https://github.com/pyeve/eve-sqlalchemy/issues/50

Кроме того, могу ли я обработать ResultModel непосредственно в дампе json в представлении, вместо того, чтобы устанавливать 2 набора результатов (с одинаковыми данными, только с другим форматированием) для отправки обратно на представление из модели?

ОБНОВЛЕНИЕ : Я понял это. Поскольку это хранимый запрос proc / direct, отображение ORM не работает, когда мы используем dict(zip(columns, row)), должны использоваться имена столбцов из запроса db. Затем для получения JSON выполните json.dumps(myDict)

Альтернативное решение: В моделях return [ResultModel(*row) for row in rows]

Просмотров:

results = Get-model
json = serializers.serialize("python", results, fields=('Column1', 'Column2')

Но это также дает мне название модели. Есть ли способ получить только часть .fields каждого возвращенного списка?

[ поля: {Column1: "1", Column2: "2"}, Модель: "app_name.resultmodel", рк: «» ]

1 Ответ

0 голосов
/ 13 сентября 2018

Попробуйте расширить JSONEncoder

import json
from decimal import Decimal

class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return float(obj)
        return json.JSONEncoder.default(self, obj)

# Usage:
d = Decimal("42.5")
json.dumps(d, cls=DecimalEncoder)
...