Dom*_*omo 6 python django json
使用Django 1.7,每当我在视图中返回以下JsonResponse时:
from django.http import JsonResponse
token = "1$aEJUhbdpO3cNrXUmFgvuR2SkXTP9="
response = JsonResponse({"token": token})
return response
Run Code Online (Sandbox Code Playgroud)
我从Web浏览器/ cURL获得以下HTTP响应:
"{\"token\": \"1$aEJUhbdpO3cNrXUmFgvuR2SkXTP9=\"}"
Run Code Online (Sandbox Code Playgroud)
我想要的,以及我在Django 1.3中所拥有的是:
{"token": "1$aEJUhbdpO3cNrXUmFgvuR2SkXTP9="}
Run Code Online (Sandbox Code Playgroud)
我有两个依赖于使用Django的私有API的移动应用程序,不幸的是他们期待第二种响应,没有额外的引号(围绕整个JSON的引号使它成为一个字符串)并且没有引用转义.
我的问题是,有没有一些内置的方法来强制Django响应不逃避JSON响应?
我编写了以下中间件来实现它,但是......它似乎是一种非常脆弱的蛮力方式:
class UnescapeJSON(object):
def process_response(self, request, response):
"""
Directly edit response object here, searching for and replacing terms
in the html.
"""
if re.search('^/api/.*', request.path):
r = response.content
r = r.replace('\\', '')
r = r.lstrip('"')
r = r.rstrip('"')
response.content = r
return response
Run Code Online (Sandbox Code Playgroud)
所以我希望有一个更聪明的方法.
背景故事是我正在尝试将旧的遗留代码库从Django 1.3更新为1.8.我目前在我的本地开发环境中使用1.7.Django 1.3以正确的方式返回JSON,没有额外的引号和反斜杠.
以这种方式返回JSON是一件好事:
{"token": "1$aEJUhbdpO3cNrXUmFgvuR2SkXTP9="}
Run Code Online (Sandbox Code Playgroud)
...是我jQuery.post({success:...})用来处理这个JSON响应,它会自动jQuery.parseJSON()为我运行,把它变成一个我可以用点表示法访问的JSON对象.
我不能只在客户端修复字符串并parseJSON()手动重新运行,因为这将涉及让我的所有用户升级他们的移动应用程序.
所以我必须按上面的方式获得JSON格式,否则我的移动API会被破坏.
我应该补充一点信息.这个API使用的是Django Piston :(.我使用的是我发现的1.7x兼容版本.现在交换Django REST框架并不适合我.相信我,我会尽快做到.
小智 7
对于在 Google 上找到此主题的人,请放弃 JsonResponse。如果您尝试使用 jsonp,则会抛出错误
“类型错误:为了允许序列化非 dict 对象,请将安全参数设置为 False”
如果您将安全设置为 False,您将收到带有引号的响应,然后在客户端失败。反而
return HttpResponse(response_data, content_type='application/json')
Run Code Online (Sandbox Code Playgroud)
我在 1.8 部署中使用 Django REST Framework 看到了这一点。我最近刚从1.3升级到1.8。然而,直到 1.8 版本我才获得 RESTful 支持,所以我不能声称它曾经起作用(或不起作用)。
该问题是由我创建 Python 字典、将它们序列化为 JSON 对象,然后对结果调用 json.dumps() 引起的。最后一步,调用 json.dumps() 并将结果传递给 Response() 构造函数,这会导致字符串被双引号括起来。
更改我的代码:
def get(self, request, year, month, day, format=None):
resp = None
date = datetime(int(year), int(month), int(day), 0, 0)
clinics = Clinic.objects.all()
for x in clinics:
aDate = datetime(x.date.year, x.date.month, x.date.day)
if date >= aDate and date <= aDate + timedelta(days=x.duration):
resp = serializers.serialize("json", [x, ])
struct = json.loads(resp)
struct[0]["fields"]["id"] = x.id
resp = json.dumps(struct[0]["fields"])
break
if resp == None:
raise NotFound()
return Response(resp)
Run Code Online (Sandbox Code Playgroud)
到
def get(self, request, year, month, day, format=None):
resp = None
date = datetime(int(year), int(month), int(day), 0, 0)
clinics = Clinic.objects.all()
for x in clinics:
aDate = datetime(x.date.year, x.date.month, x.date.day)
if date >= aDate and date <= aDate + timedelta(days=x.duration):
resp = serializers.serialize("json", [x, ])
struct = json.loads(resp)
struct[0]["fields"]["id"] = x.id
resp = struct[0]["fields"]
break
if resp == None:
raise NotFound()
return Response(resp)
Run Code Online (Sandbox Code Playgroud)
修复了 Django REST 中的问题(对我来说)。(请注意,我分配 resp 的行是唯一需要更改的行)。希望这能有所帮助。
| 归档时间: |
|
| 查看次数: |
3355 次 |
| 最近记录: |