在 Django 中导致错误的有效 (?) JSON 数据必须作为字符串提供给前端并由 javascript 中的 JSON.parse() 转换 - 为什么?
Valid (?) JSON data causing errors in Django, must be served to frontend as string and converted by JSON.parse() in javascript - why?
我在我的 Django 目录中本地托管了一个 JSON 文件。它从该文件中提取到 views.py 中的视图,在其中像这样读入:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data1 = json.load(json_data) # deserialises it
data2 = json.dumps(data1) # json formatted string
json_data.close()
return JsonResponse(data2, safe=False)
在没有 (safe=False) 的情况下使用 JsonResponse returns 出现以下错误:
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
同样,使用 json.loads(json_data.read()) 而不是 json.load 会出现此错误:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
这让我感到困惑 - 我已经使用在线验证器验证了 JSON。当使用 safe=False 将 JSON 发送到前端时,到达的结果对象是一个字符串,即使在 javascript 中调用 .json() 之后也是如此:
fetch("/json").then(response => {
return response.json();
}).then(data => {
console.log("data ", data); <---- This logs a string to console
...
然而,再往前一步并在字符串上调用 JSON.parse() 会将对象转换为我可以按预期使用的 JSON 对象
data = JSON.parse(data);
console.log("jsonData", data); <---- This logs a JSON object to console
但这个解决方案并不完整。
在这一点上,我认为最有可能的是源 JSON 有问题 -(在文件字符编码中?)或者 json.dumps() 没有做我认为它应该是什么,或者我不了解 Django API 的 JSON 响应功能,我不知道...
我已经达到了我对这个主题的了解的极限。如果您有什么智慧可以传授,我将不胜感激。
编辑:正如 Abdul 在下面的回答中一样,我将 JSON 重新格式化为带有 json.dumps(data1) 行
的字符串
工作代码如下:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data = json.load(json_data) # deserialises it
json_data.close()
return JsonResponse(data, safe=False) # pass the python object here
让我们看看您的以下代码行:
json_data = open(finders.find('JSON/myjson.json'))
data1 = json.load(json_data) # deserialises it
data2 = json.dumps(data1) # json formatted string
您打开一个文件并在 json_data
中获取一个文件指针,解析其内容并在 data1
中获取一个 python 对象,然后将其 返回 转换为 JSON 字符串 并将其存储到 data2
中。有点多余吧?接下来,您将此 JSON 字符串传递给 JsonResponse
,后者将进一步尝试将其序列化为 JSON!!意思是你然后在 JSON.
中的字符串中得到一个字符串
请尝试使用以下代码:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data = json.load(json_data) # deserialises it
json_data.close()
return JsonResponse(data, safe=False) # pass the python object here
Note: function names in python should ideally be in snake_case
not PascalCase
, hence instead of Stops
you should use stops
. See
PEP 8 -- Style Guide for Python
Code
我在我的 Django 目录中本地托管了一个 JSON 文件。它从该文件中提取到 views.py 中的视图,在其中像这样读入:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data1 = json.load(json_data) # deserialises it
data2 = json.dumps(data1) # json formatted string
json_data.close()
return JsonResponse(data2, safe=False)
在没有 (safe=False) 的情况下使用 JsonResponse returns 出现以下错误:
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
同样,使用 json.loads(json_data.read()) 而不是 json.load 会出现此错误:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
这让我感到困惑 - 我已经使用在线验证器验证了 JSON。当使用 safe=False 将 JSON 发送到前端时,到达的结果对象是一个字符串,即使在 javascript 中调用 .json() 之后也是如此:
fetch("/json").then(response => {
return response.json();
}).then(data => {
console.log("data ", data); <---- This logs a string to console
...
然而,再往前一步并在字符串上调用 JSON.parse() 会将对象转换为我可以按预期使用的 JSON 对象
data = JSON.parse(data);
console.log("jsonData", data); <---- This logs a JSON object to console
但这个解决方案并不完整。
在这一点上,我认为最有可能的是源 JSON 有问题 -(在文件字符编码中?)或者 json.dumps() 没有做我认为它应该是什么,或者我不了解 Django API 的 JSON 响应功能,我不知道...
我已经达到了我对这个主题的了解的极限。如果您有什么智慧可以传授,我将不胜感激。
编辑:正如 Abdul 在下面的回答中一样,我将 JSON 重新格式化为带有 json.dumps(data1) 行
的字符串工作代码如下:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data = json.load(json_data) # deserialises it
json_data.close()
return JsonResponse(data, safe=False) # pass the python object here
让我们看看您的以下代码行:
json_data = open(finders.find('JSON/myjson.json'))
data1 = json.load(json_data) # deserialises it
data2 = json.dumps(data1) # json formatted string
您打开一个文件并在 json_data
中获取一个文件指针,解析其内容并在 data1
中获取一个 python 对象,然后将其 返回 转换为 JSON 字符串 并将其存储到 data2
中。有点多余吧?接下来,您将此 JSON 字符串传递给 JsonResponse
,后者将进一步尝试将其序列化为 JSON!!意思是你然后在 JSON.
请尝试使用以下代码:
def Stops(request):
json_data = open(finders.find('JSON/myjson.json'))
data = json.load(json_data) # deserialises it
json_data.close()
return JsonResponse(data, safe=False) # pass the python object here
Note: function names in python should ideally be in
snake_case
notPascalCase
, hence instead ofStops
you should usestops
. See PEP 8 -- Style Guide for Python Code