591

I'm trying to convert a server side Ajax response script into a Django HttpResponse, but apparently it's not working.

This is the server-side script:

/* RECEIVE VALUE */ $validateValue=$_POST['validateValue']; $validateId=$_POST['validateId']; $validateError=$_POST['validateError']; /* RETURN VALUE */ $arrayToJs = array(); $arrayToJs[0] = $validateId; $arrayToJs[1] = $validateError; if($validateValue =="Testuser"){ // Validate?? $arrayToJs[2] = "true"; // RETURN TRUE echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}'; // RETURN ARRAY WITH success } else{ for($x=0;$x<1000000;$x++){ if($x == 990000){ $arrayToJs[2] = "false"; echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}'; // RETURNS ARRAY WITH ERROR. } } } 

And this is the converted code

def validate_user(request): if request.method == 'POST': vld_value = request.POST.get('validateValue') vld_id = request.POST.get('validateId') vld_error = request.POST.get('validateError') array_to_js = [vld_id, vld_error, False] if vld_value == "TestUser": array_to_js[2] = True x = simplejson.dumps(array_to_js) return HttpResponse(x) else: array_to_js[2] = False x = simplejson.dumps(array_to_js) error = 'Error' return render_to_response('index.html',{'error':error},context_instance=RequestContext(request)) return render_to_response('index.html',context_instance=RequestContext(request)) 

I'm using simplejson to encode the Python list (so it will return a JSON array). I couldn't figure out the problem yet. But I think that I did something wrong about the 'echo'.

1
  • You can also use the django-annoying view decorator @ajax_request.
    – zopieux
    CommentedApr 13, 2014 at 23:22

17 Answers 17

1109

I usually use a dictionary, not a list to return JSON content.

import json from django.http import HttpResponse response_data = {} response_data['result'] = 'error' response_data['message'] = 'Some error message' 

Pre-Django 1.7 you'd return it like this:

return HttpResponse(json.dumps(response_data), content_type="application/json") 

For Django 1.7+, use JsonResponse as shown in this SO answer like so :

from django.http import JsonResponse return JsonResponse({'foo':'bar'}) 
3
  • 6
    It is the mimetype, not the list that should be getting him into trouble. While most JSON is typically an object ("dictionary") at the top level, JSON is perfectly happy with an array at the top-level.
    – Thanatos
    CommentedJun 20, 2012 at 21:39
  • 7
    Sorry, it's not clear from what I wrote, but I only meant I use a dictionary because it's cleaner/ easier when serializing it to JSON.
    – Tom
    CommentedJun 21, 2012 at 15:17
  • 'application/json' is not properly supported in older versions of IE. Here is some discussion of the issue github.com/blueimp/jQuery-File-Upload/issues/123
    – Victory
    CommentedApr 25, 2014 at 22:05
206

New in django 1.7

you could use JsonResponse objects.

from the docs:

from django.http import JsonResponse return JsonResponse({'foo':'bar'}) 
2
  • 2
    One downside: it defaults to ensure_ascii and I didn't find a way to override it yet. Created a new question for this: stackoverflow.com/q/34798703/854477
    – int_ua
    CommentedJan 14, 2016 at 20:07
  • @int_ua: just add json_dumps_params={"ensure_ascii": False} (requires Django 1.9 or newer)CommentedNov 9, 2019 at 16:18
157

I use this, it works fine.

from django.utils import simplejson from django.http import HttpResponse def some_view(request): to_json = { "key1": "value1", "key2": "value2" } return HttpResponse(simplejson.dumps(to_json), mimetype='application/json') 

Alternative:

from django.utils import simplejson class JsonResponse(HttpResponse): """ JSON response """ def __init__(self, content, mimetype='application/json', status=None, content_type=None): super(JsonResponse, self).__init__( content=simplejson.dumps(content), mimetype=mimetype, status=status, content_type=content_type, ) 

In Django 1.7 JsonResponse objects have been added to the Django framework itself which makes this task even easier:

from django.http import JsonResponse def some_view(request): return JsonResponse({"key": "value"}) 
4
  • 1
    The problem is here it's not getting the value from the input field vld_value = request.POST.get('validateValue')
    – Switch
    CommentedMar 11, 2010 at 20:11
  • 3
    With python 2.7, it should just be "import json"CommentedSep 6, 2012 at 22:22
  • 1
    I think from django.utils import simplejson is for backwards compatibility.CommentedFeb 10, 2013 at 5:29
  • 1
    JsonResponse(status=404, data={'status':'false','message':message})
    – Belter
    CommentedSep 8, 2017 at 14:28
27

Since Django 1.7 you have a standard JsonResponse that's exactly what you need:

from django.http import JsonResponse ... return JsonResponse(array_to_js, safe=False) 

You don't even need to json.dump your array.

0
    27

    With Django Class-based views you can write:

    from django.views import View from django.http import JsonResponse class JsonView(View): def get(self, request): return JsonResponse({'some': 'data'}) 

    and with Django-Rest-Framework you can write:

    from rest_framework.views import APIView from rest_framework.response import Response class JsonView(APIView): def get(self, request): return Response({'some': 'data'}) 
    0
      21

      For those who use Django 1.7+

      from django.http import JsonResponse def your_view(request): json_object = {'key': "value"} return JsonResponse(json_object) 

      official docs

        18
        from django.http import HttpResponse import json class JsonResponse(HttpResponse): def __init__(self, content={}, mimetype=None, status=None, content_type='application/json'): super(JsonResponse, self).__init__(json.dumps(content), mimetype=mimetype, status=status, content_type=content_type) 

        And in the view:

        resp_data = {'my_key': 'my value',} return JsonResponse(resp_data) 
        0
          12

          You'll want to use the django serializer to help with unicode stuff:

          from django.core import serializers json_serializer = serializers.get_serializer("json")() response = json_serializer.serialize(list, ensure_ascii=False, indent=2, use_natural_keys=True) return HttpResponse(response, mimetype="application/json") 
          1
          11

          Its very convenient with Django version 1.7 or higher as you have the JsonResponse class, which is a subclass of HttpResponse.

          from django.http import JsonResponse def profile(request): data = { 'name': 'Raghav', 'location': 'India', 'is_active': False, 'count': 28 } return JsonResponse(data) 

          For older versions of Django, you must use an HttpResponse object.

          import json from django.http import HttpResponse def profile(request): data = { 'name': 'Raghav', 'location': 'India', 'is_active': False, 'count': 28 } dump = json.dumps(data) return HttpResponse(dump, content_type='application/json') 
          1
          • Extractly right!CommentedApr 8, 2022 at 2:32
          8

          How to use google app engine with ajax (json)?

          Code Javascript with JQuery:

          $.ajax({ url: '/ajax', dataType : 'json', cache: false, success: function(data) { alert('Load was performed.'+data.ajax_resp); } }); 

          Code Python

          class Ajax(webapp2.RequestHandler): def get(self): my_response = {'ajax_resp':'Hello, webapp World!'} datos = json.dumps(my_response) self.response.headers.add_header('content-type', 'application/json', charset='utf-8') self.response.out.write(datos) 
            6

            First import this:

            from django.http import HttpResponse 

            If you have the JSON already:

            def your_method(request): your_json = [{'key1': value, 'key2': value}] return HttpResponse(your_json, 'application/json') 

            If you get the JSON from another HTTP request:

            def your_method(request): response = request.get('https://www.example.com/get/json') return HttpResponse(response, 'application/json') 
              5

              This is my preferred version using a class based view. Simply subclass the basic View and override the get()-method.

              import json class MyJsonView(View): def get(self, *args, **kwargs): resp = {'my_key': 'my value',} return HttpResponse(json.dumps(resp), mimetype="application/json" ) 
                5

                Django code views.py:

                def view(request): if request.method == 'POST': print request.body data = request.body return HttpResponse(json.dumps(data)) 

                HTML code view.html:

                <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script> $(document).ready(function(){ $("#mySelect").change(function(){ selected = $("#mySelect option:selected").text() $.ajax({ type: 'POST', dataType: 'json', contentType: 'application/json; charset=utf-8', url: '/view/', data: { 'fruit': selected }, success: function(result) { document.write(result) } }); }); }); </script> </head> <body> <form> {{data}} <br> Select your favorite fruit: <select id="mySelect"> <option value="apple" selected >Select fruit</option> <option value="apple">Apple</option> <option value="orange">Orange</option> <option value="pineapple">Pineapple</option> <option value="banana">Banana</option> </select> </form> </body> </html> 
                  4

                  Most of these answers are out of date. JsonResponse is not recommended because it escapes the characters, which is usually undesired. 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') 

                  Bonus for Vue Users

                  If you want to bring your Django Queryset into Vue, you can do the following.

                  template.html

                  <div id="dataJson" style="display:none"> {{ data }} </div> <script> let dataParsed = JSON.parse(document.getElementById('dataJson').textContent); var app = new Vue({ el: '#app', data: { yourVariable: dataParsed, }, }) </script> 
                    4

                    This way the json contents can be downloaded as a file with a specific filename.

                    import json from django.http import HttpResponse def download_json(request): data = {'some': 'information'} # serialize data obj as a JSON stream data = json.dumps(data) response = HttpResponse(data, content_type='application/json charset=utf-8') # add filename to response response['Content-Disposition'] = 'attachment; filename="filename.json"' return response 
                      1

                      In View use this:

                      form.field.errors|striptags 

                      for getting validation messages without html

                        1
                        def your_view(request): response = {'key': "value"} return JsonResponse(json.dumps(response), content_type="application/json",safe=False) 

                        #Specify the content_type and use json.dump() son as the content not to be sent as object

                        1
                        • 2
                          If you call django.http.JsonResponse() you dont have to dump the content and the default content_type is already set to application/jsonCommentedNov 10, 2021 at 21:42

                        Start asking to get answers

                        Find the answer to your question by asking.

                        Ask question

                        Explore related questions

                        See similar questions with these tags.