4

I am using python and django to develop some REST APIs. I have a question about the JSON unicode string returned by the requests call. So, I am doing something like:

resp = requests.get(self.url)
if resp.status_code is status.HTTP_200_OK:
    obj = json.loads(resp.json())

With this I can iterate over the entries as:

for o in obj:
    print o

This prints something like:

{u'pk': 1, u'model': u'aslapp.imagetypemodel', u'fields': {u'type': u'PNG'}}
{u'pk': 2, u'model': u'aslapp.imagetypemodel', u'fields': {u'type': u'JPG'}}

However, I read that the resp.json() call should call this json.loads() method internally and will take care of the encoding stuff. However, just doing:

obj = resp.json()
for o in obj:
    print o

Just iterates over each character in the unicode string. So am I supposed to run it through the loads method again if I want to iterate through the JSON entries? What would be the correct way to iterate through all the JSON records returned returned by resp.json().

user2390182
  • 72,016
  • 6
  • 67
  • 89
Luca
  • 10,458
  • 24
  • 107
  • 234
  • I'm a little confused - `requests.get` is related to django or [requests](http://docs.python-requests.org/en/master/)? – dahrens Nov 21 '16 at 16:57

1 Answers1

5

You are correct, resp.json() does call json.loads() for you.

Therefore, if resp.json() returns a string, then that suggests that the API has json encoded the data twice. For example, it is returning "{\"pk\": 1}" instead of {"pk": 1}.

If you don't have any control over the API, then you'll have to decode it twice to get the Python object.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Right. So on the django side, the returned data is `data = serializers.serialize("json", types) return Response(data)` – Luca Nov 21 '16 at 16:53
  • 1
    @Luca Django also has a `JsonResponse` which you can pass objects like dicts or lists directly. – user2390182 Nov 21 '16 at 16:55
  • 2
    If Response is from DRF, then it will serialize things for you; as the DRF docs note, you should pass in Python primitives (eg dicts and lists) rather than already-rendered JSON. Use the standard HttpResponse, or use DRF's serializers rather than the Django ones. – Daniel Roseman Nov 21 '16 at 16:57
  • 1
    @Luca Sound advice by Daniel Roseman. (DRF = django-rest-framework) You should definitely consider it if you are building an API. – user2390182 Nov 21 '16 at 17:01
  • Thanks for the great suggestions! – Luca Nov 21 '16 at 17:03
  • 1
    Thanks again to all. I was able to use the `Serializer` classes from DRF and learn something new in the process! – Luca Nov 21 '16 at 17:29