Create JSON Response in Django with Model

30,540

Solution 1

You should use django serializers instead of simplejson:

For example, this returns correctly serialized data:

from django.core import serializers
# serialize queryset
serialized_queryset = serializers.serialize('json', some_queryset)
# serialize object
serialized_object = serializers.serialize('json', [some_object,])

Solution 2

Method-1: Use Django's python serializer

I think this answer won't return a JSON or a Python dict/list object. So, use the format python instead of json

from django.core import serializers
# serialize queryset
serialized_queryset = serializers.serialize('python', some_queryset)
# serialize object
serialized_object = serializers.serialize('python', [some_object,])

Django shell response

In [2]: from django.core import serializers                                                                                                                             

In [3]: qs = SomeModel.objects.all()                                                                                                                                    

In [4]: json_res = serializers.serialize('json',qs)                                                                                                                     

In [5]: type(json_res)                                                                                                                                                  
Out[5]: str

In [6]: python_res = serializers.serialize('python',qs)                                                                                                                 

In [7]: type(python_res)                                                                                                                                                
Out[7]: list
#views.py
from django.core import serializers
from django.http.response import JsonResponse


def some_view(request):
    some_queryset = SomeModel.objects.all()
    serialized_queryset = serializers.serialize('python', some_queryset)
    return JsonResponse(serialized_queryset, safe=False)

Method-2: Use Django's values() method

The direct use of values() method will throw TypeError exception, so convert the QuerySet to a python list as below,

from django.http.response import JsonResponse


def sample_view(request):
    return JsonResponse(list(SomeModel.objects.all().values()), safe=False)
Share:
30,540
abisson
Author by

abisson

Updated on May 08, 2020

Comments

  • abisson
    abisson almost 4 years

    I am having some issue here. I am trying to return a JSON response made of a message and a model instance:

       class MachineModel(models.Model):
           name = models.CharField(max_length=64, blank=False)
           description = models.CharField(max_length=64, blank=False)
           manufacturer = models.ForeignKey(Manufacturer)
           added_by = models.ForeignKey(User, related_name='%(app_label)s_%(class)s_added_by')
           creation_date = models.DateTimeField(auto_now_add=True)
           last_modified = models.DateTimeField(auto_now=True)
    
        machine_model_model = form.save(commit=False)
        r_user = request.user.userprofile
        machine_model_model.manufacturer_id = manuf_id
        machine_model_model.added_by_id = request.user.id
        machine_model_model.save()
        alert_message = " The'%s' model " % machine_model_model.name
        alert_message += ("for '%s' " % machine_model_model.manufacturer)
        alert_message += "was was successfully created!"
        test = simplejson.dumps(list(machine_model_model))
        data = [{'message': alert_message, 'model': test}]
        response = JSONResponse(data, {}, 'application/json')
    
    
    class JSONResponse(HttpResponse):
    """JSON response class."""
        def __init__(self, obj='', json_opts={}, mimetype="application/json", *args, **kwargs):
            content = simplejson.dumps(obj, **json_opts)
            super(JSONResponse,self).__init__(content, mimetype, *args, **kwargs)
    

    But I keep getting:

    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o) + " is not JSON serializable")
    
    TypeError: <MachineModel: "Test12"> is not JSON serializable
    

    Why is that? I have seen before:

    models = Model.objects.filter(manufacturer_id=m_id)
    json = simplejson.dumps(models)
    

    and that works... what is the difference?!

    Thanks!

  • abisson
    abisson over 11 years
    I don't really get a JSON object... I get "[{"pk": 86, "model": "machine_models.machinemodel", "fields": {"name": "MX10", "description": "lol", "creation_date": "2012-09-23T16:50:35.709Z", "last_modified": "2012-09-23T16:50:35.709Z", "added_by": 2, "manufacturer": "1"}}]"
  • Serhii Holinei
    Serhii Holinei over 11 years
    It is actualy JSON object. You can deserialize it on a template. By jquery, for example: jQuery.parseJSON(response), which returns a javascript dictionary.
  • abisson
    abisson over 11 years
    Ok good it works! But I always get an array (in JQuery and I have to take the first [0]... Is that normal?! It is kind of annoying as well. Would you recommend a REST Api?!
  • Serhii Holinei
    Serhii Holinei over 11 years
    As the second argument of serialize method can be any iterator that yields Django model instances (taken from docs), I dont know any other method to handle with single model instance serialization. Also, checkout this relative question. About REST Api - sorry, I am not competent in this area. Btw, I use the same descriptions in my projects :-)
  • JPG
    JPG over 4 years
    @Radesh What happened with method-1?
  • Radesh
    Radesh over 4 years
    return json response contain some extra /" like this : [{\"model\": \"api\"
  • Ulvi
    Ulvi almost 4 years
    @JPG, is it equally the same to use either of these methods? Do any of these have any drawbacks in performance or another thing? I personally see using second method very easy but also curious about if it has any disadvantage.
  • Joe Sadoski
    Joe Sadoski over 2 years
    I'm not a big fan of using safe=false, but in my application, I was able to put the list into a dictionary to make the JsonResponse serializer happy: return JsonResponse({ "someObjects": list(SomeModel.objects.all().values()) })