J.Woo J.Woo - 29 days ago 8
JSON Question

django.http.JsonResponse return json data in wrong format

I want to return the

queryset
in json format, and I use the
JsonResponse
as the following:

def all_alert_history(request):
''' get all all alert history data '''
all_data_json = serializers.serialize('json', LatestAlert.objects.all())
return JsonResponse(all_data_json,safe=False)


but the browser shows like this:

"[{\"fields\": {\"alert_name\": \"memory usage\", \"alert_value\": 83.7, \"alert_time\": \"2016-11-08T06:21:20.717Z\", \"alert_level\": \"warning\", \"alert_rule\": \"warning: > 80%\"}, \"model\": \"alert_handler.latestalert\", \"pk\": \"xyz.test-java.ip-10-0-10-138.memory.percent\"}]"


I replace the
JsonResponse
with
HttpResponse
:

def all_alert_history(request):
''' get all all alert history data '''
all_data_json = serializers.serialize('json', LatestAlert.objects.all())
return HttpResponse(all_data_json, content_type='application/json')


and the browser shows like this:

[{"fields": {"alert_name": "memory usage", "alert_value": 83.7, "alert_time": "2016-11-08T06:21:20.717Z", "alert_level": "warning", "alert_rule": "warning: > 80%"}, "model": "alert_handler.latestalert", "pk": "xyz.test-java.ip-10-0-10-138.memory.percent"}]


so, why does the
\
appears when I use the
JsonResponse
but disappear when use the
HttpResponse
?

django
version:
1.8

Answer

JsonResponse takes a python dictionary and returns it as a json formatted string for the browser.

Since you're providing the JsonResponse with an already json formatted string it will try to escape all necessary characters with \.

Example:

>>> from django.http import JsonResponse
>>> response = JsonResponse({'foo': 'bar'})
>>> response.content
b'{"foo": "bar"}'

In your case JsonResponse even warns you about what you are doing when passing a string, hence making the safe = False parameter necessary:

>>> mydata = {"asd":"bdf"}
>>> import json
>>> myjson = json.dumps(mydata)
>>> JsonResponse(myjson)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/swozny/work2/local/lib/python2.7/site-packages/django/http/response.py", line 500, in __init__
    raise TypeError('In order to allow non-dict objects to be '
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False

With the parameter set to False your observed behavior is reproducible:

>>> JsonResponse(myjson,safe=False).content
'"{\\"asd\\": \\"bdf\\"}"'

Bottom line is that if your model is a little more complex than basic data types ( IntegerField,CharField,...) then you probably will want to do the serialization yourself and stick to HttpResponse or just use djangorestframework which offers tools to do it for you.