Django JsonResponse 将数字转换为字符串
Django JsonResponse converts numbers to string
我正在从我的 Django 后端 API 使用 JsonResponse(status=200, data=<python_dict_with_data>)
到 return。然而,在检查结果时,所有数值都被转换为字符串(这些值是字典的值部分,而不是键)。这会在接收此响应的前端产生问题,因为现在我必须将它们解析为整数以进行格式化和轻量级计算。当从 Django returned 时,有没有办法阻止这种转换?
或者有没有办法在前端正确解析响应?我在前端的 React 中使用 Axios 库。
Is there a way to prevent this conversion when returned from Django?
键确实会被转换成字符串,因为整数作为键在JSON中是非法。事实上,如果你使用像 JSONLint 这样的验证器,你会看到 {1: 1}
是无效的 JSON,而 { "1": 1 }
是有效的 JSON。 Python JSON 编码器因此将回退到将整数转换为字符串,以仍然生成有效内容。
如果您必须进行轻量级计算,使用这些作为 keys 可能不是一个好主意。例如,如果您的数据如下所示:
{ 1: 4, 2: 5 }
您可以考虑重组数据,例如:
{ "data": [ {"key": 1, "value": 4}, {"key": 2, "value": 5} ] }
您也可以 return 它作为 HTTP 响应,并在 JavaScript 结束时进行解析,但可能只会导致更多麻烦。
对于Decimal
个数字,它也会使用字符串。 Django 默认使用 DjangoJSONEncoder [Django-doc] which:
Decimal
, Promise
(django.utils.functional.lazy()
objects), UUID
:
A string representation of the object.
例如,如果我们编码 Decimal
,我们会看到:
>>> djenc = DjangoJSONEncoder()
>>> djenc.encode({'a': Decimal('0.25')})
'{"a": "0.25"}'
您可以将编码器子类化,并将 Decimal
解析为 float
,但请注意,这可能会导致 精度损失 。这正是使用字符串的原因:确保没有数字丢失:
from django.core.serializers.json import DjangoJSONEncoder
from decimal import Decimal
class MyDjangoJSONEncoder(DjangoJSONEncoder):
def <b>default</b>(self, o):
if <b>isinstance(o, Decimal)</b>:
return float(o)
return super().default(o)
然后生成:
>>> mydjenc = MyDjangoJSONEncoder()
>>> mydjenc.encode({'a': Decimal('0.25')})
'{"a": 0.25}'
然后您可以在 JsonResponse
:
中使用此编码器
from decimal import Decimal
def myview(request):
# …
JsonResponse(<b>encoder=MyDjangoJSONEncoder</b>, data={'a': Decimal('0.25')})
我正在从我的 Django 后端 API 使用 JsonResponse(status=200, data=<python_dict_with_data>)
到 return。然而,在检查结果时,所有数值都被转换为字符串(这些值是字典的值部分,而不是键)。这会在接收此响应的前端产生问题,因为现在我必须将它们解析为整数以进行格式化和轻量级计算。当从 Django returned 时,有没有办法阻止这种转换?
或者有没有办法在前端正确解析响应?我在前端的 React 中使用 Axios 库。
Is there a way to prevent this conversion when returned from Django?
键确实会被转换成字符串,因为整数作为键在JSON中是非法。事实上,如果你使用像 JSONLint 这样的验证器,你会看到 {1: 1}
是无效的 JSON,而 { "1": 1 }
是有效的 JSON。 Python JSON 编码器因此将回退到将整数转换为字符串,以仍然生成有效内容。
如果您必须进行轻量级计算,使用这些作为 keys 可能不是一个好主意。例如,如果您的数据如下所示:
{ 1: 4, 2: 5 }
您可以考虑重组数据,例如:
{ "data": [ {"key": 1, "value": 4}, {"key": 2, "value": 5} ] }
您也可以 return 它作为 HTTP 响应,并在 JavaScript 结束时进行解析,但可能只会导致更多麻烦。
对于Decimal
个数字,它也会使用字符串。 Django 默认使用 DjangoJSONEncoder [Django-doc] which:
Decimal
,Promise
(django.utils.functional.lazy()
objects),UUID
: A string representation of the object.
例如,如果我们编码 Decimal
,我们会看到:
>>> djenc = DjangoJSONEncoder()
>>> djenc.encode({'a': Decimal('0.25')})
'{"a": "0.25"}'
您可以将编码器子类化,并将 Decimal
解析为 float
,但请注意,这可能会导致 精度损失 。这正是使用字符串的原因:确保没有数字丢失:
from django.core.serializers.json import DjangoJSONEncoder
from decimal import Decimal
class MyDjangoJSONEncoder(DjangoJSONEncoder):
def <b>default</b>(self, o):
if <b>isinstance(o, Decimal)</b>:
return float(o)
return super().default(o)
然后生成:
>>> mydjenc = MyDjangoJSONEncoder()
>>> mydjenc.encode({'a': Decimal('0.25')})
'{"a": 0.25}'
然后您可以在 JsonResponse
:
from decimal import Decimal
def myview(request):
# …
JsonResponse(<b>encoder=MyDjangoJSONEncoder</b>, data={'a': Decimal('0.25')})