25

I saw that now in Django 1.7 I can use the http.JSONResponse object to send JSON to a client. My View is:

#Ajax
def get_chat(request):
    usuario = request.GET.get('usuario_consultor', None)
    usuario_chat = request.GET.get('usuario_chat', None)

    mensajes = list(MensajeDirecto.objects.filter(Q(usuario_remitente = usuario, usuario_destinatario = usuario_chat) | Q(usuario_remitente = usuario_chat, usuario_destinatario = usuario)))


    return JsonResponse(mensajes, safe=False)

But I get the next error:

<MensajeDirecto: Towi CrisTowi> is not JSON serializable`

Do you know how to serialize a QuerySet to send it back in JSON form?

Cris_Towi
  • 615
  • 1
  • 13
  • 25
  • Check this link http://stackoverflow.com/questions/26067369/how-to-pass-model-fields-to-a-jsonresponse-object – Arun Ghosh Oct 15 '14 at 06:52

2 Answers2

69

You shouldn't re-serialize with JsonResponse. You'll get a correctly formatted JSON response with:

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

def my_view(request):
    my_model = MyModel.objects.all()
    response = serializers.serialize("json", my_model)
    return HttpResponse(response, content_type='application/json')

If you use a JsonResponse, it will coerce the already serialized JSON to a string, which is probably not what you want.

Note: Works with Django 1.10

Daniel van Flymen
  • 10,931
  • 4
  • 24
  • 39
16
from django.core import serializers
from django.http import JsonResponse

def get_chat(request):
    usuario = request.GET.get('usuario_consultor', None)
    usuario_chat = request.GET.get('usuario_chat', None)

    mensajes = MensajeDirecto.objects.filter(Q(usuario_remitente = usuario, usuario_destinatario = usuario_chat) | Q(usuario_remitente = usuario_chat, usuario_destinatario = usuario))

    return JsonResponse(serializers.serialize('json', mensajes), safe=False)

Ref: https://docs.djangoproject.com/en/dev/ref/request-response/#jsonresponse-objects https://docs.djangoproject.com/en/1.7/topics/serialization/

micrypt
  • 431
  • 4
  • 10
  • We can also use HttpResponse instead of JsonResponse: return HttpResponse(serializers.serialize('json', mensajes)) – jatinkumar patel Feb 19 '15 at 06:40
  • 3
    @jatin You do want to use JsonResponse to ensure that the `Content-Type` header is set to `application/json`. – micrypt May 06 '15 at 07:36
  • 6
    `return JsonResponse(serializers.serialize('json', data), safe=False)` returns me JSON String instead of JSON... `return HttpResponse(serializers.serialize('json', data), content_type="application/json")` works sell. – Arst Sep 12 '16 at 09:53
  • @Arst JsonResponse is a subclass of HttpResponse with the `content_type` parameter already preset to `application/json`. Thus using a HttpResponse is essentially manually constructing a similar result. Perhaps look for another cause if the header isn't being set. Source: https://docs.djangoproject.com/en/1.10/ref/request-response/#jsonresponse-objects – micrypt Sep 12 '16 at 15:22
  • 4
    @Arst is correct. If you use `JsonResponse`, you're essentially re-serializing an already JSON string. See my answer below. – Daniel van Flymen Sep 29 '16 at 15:03
  • `serializers` is a stupid class, which not suitable with `JsonResponse`. it doing to much, return dumped `json` string instead of dict. the answer below is correct. Developers have to set mime manually. – PaleNeutron Apr 17 '18 at 05:36