9

I'm working in Django 1.8 and having trouble finding the modern way to do this.

This is what I've got, based on Googling and this blog post:

results = PCT.objects.filter(code__startswith='a')
json_res = []
for result in results:
    json_res.append(result.as_dict())
return HttpResponse(json.dumps(json_res), content_type='application/json')

However this gives me 'PCT' object has no attribute 'as_dict'.

Surely there must be a neater way by now?

I was wondering if it was possible to use JSONResponse but frustratingly, the docs give no example of how to use JSONRespose with a queryset, which must be the most common use case. I have tried this:

results = PCT.objects.filter(code__startswith='a')
return JsonResponse(results, safe=False)

This gives [<PCT: PCT object>, <PCT: PCT object>] is not JSON serializable.

isherwood
  • 52,576
  • 15
  • 105
  • 143
Richard
  • 57,831
  • 112
  • 317
  • 501
  • possible duplicate of [Creating a JSON response using Django and Python](http://stackoverflow.com/questions/2428092/creating-a-json-response-using-django-and-python) – John Schmitt May 14 '15 at 17:08
  • but *surely* things must have got simpler since 2010? – Richard May 14 '15 at 17:09
  • They surely have, and it's referenced in the first answer to the duplicate question. – John Schmitt May 14 '15 at 17:10
  • ok, so that links to here: http://stackoverflow.com/questions/2428092/creating-a-json-response-using-django-and-python/24411716#24411716 which shows how to return a dictionary using JSONResponse. But I have a QuerySet, not a dictionary. I'm trying `return JsonResponse(results.values(), safe=False)` but that gives me a `TypeError: not JSON serializable`. Any ideas? – Richard May 14 '15 at 17:14
  • I'm really not trying to be difficult, but this does seem like one of the most common things one might want to do in Django, given the move to front-end apps: I'm surprised it's so difficult to figure out how to do it. – Richard May 14 '15 at 17:15
  • If all you want to do is return the result of a model-query as part of a GET, then this sounds like a REST-compatible call. Did you have a look at the [REST-framework](http://www.django-rest-framework.org/)? – mknecht May 14 '15 at 17:22
  • @mknecht looks like I may have to use that if this is impossible, but seems a bit heavyweight - I just want a simple JSON method that I can use for an autocomplete field, not a full RESTful API. – Richard May 14 '15 at 17:25
  • I really don't think this question is a duplicate: the "duplicate" is ancient, and yes it has a recent update, but the update is about converting a dictionary to JSON, not a QuerySet, so that's quite different. – Richard May 14 '15 at 17:26

4 Answers4

29

Simplest solution without any additional framework:

results = PCT.objects.filter(code__startswith='a').values('id', 'name')
return JsonResponse({'results': list(results)})

returns {'results': [{'id': 1, 'name': 'foo'}, ...]}

or if you only need the values:

results = PCT.objects.filter(code__startswith='a').values_list('id', 'name')
return JsonResponse({'results': list(results)})

returns {'results': [[1, 'foo'], ...]}

Leistungsabfall
  • 6,143
  • 7
  • 32
  • 41
  • So close! But the first snippet gives me the following error message: `[{'code': u'5M1', 'name': u'South Birmingham'}, {'code': u'5M3', 'name': u'Walsall Teaching'}`] is not JSON serializable`. – Richard May 14 '15 at 17:20
  • 3
    This doesn't work for me :( I get a ` is not JSON serializable` with `return JsonResponse({'results': list(results)})` – cfraser Jul 13 '17 at 16:15
5

use values() to return a querydict, and pass that to json.dumps

values = PCT.objects.filter(code__startswith='a').values()
return HttpResponse(json.dumps(values), content_type='application/json')

https://docs.djangoproject.com/en/1.8/ref/models/querysets/#values

wobbily_col
  • 10,271
  • 11
  • 56
  • 78
  • 1
    Thansk, but same problem as with other answers: `TypeError... is not JSON serializable`. – Richard May 14 '15 at 17:24
  • strange, it should work. http://stackoverflow.com/questions/25798395/python-query-dict-to-json. Maybe try calling the dict() method on values. – wobbily_col May 14 '15 at 17:32
2

Most of these answers are out of date. Here's what I use:

views.py (returns HTML)

from django.shortcuts import render
from django.core import serializers

def your_view(request):
    data = serializers.serialize('json', YourModel.objects.all())
    context = {"data":data}
    return render(request, "your_view.html", context)

views.py (returns JSON)

from django.core import serializers
from django.http import HttpResponse

def your_view(request):
    data = serializers.serialize('json', YourModel.objects.all())
    return HttpResponse(data, content_type='application/json')
devdrc
  • 1,362
  • 11
  • 19
0

Take a look at Django's serialization framework. It allows not only the XML format, but also JSON and YAML.

Adrian Ghiuta
  • 1,470
  • 16
  • 26
  • Thanks, having read through that page I've got as far as `data = serializers.serialize("json", results)` and then `return data` but that gives me an error message about Unicode. Is there a missing step? – Richard May 14 '15 at 17:20