Output Django queryset as JSON

Solution 1:

You can use JsonResponse with values. Simple example:

from django.http import JsonResponse

def some_view(request):
    data = list(SomeModel.objects.values())  # wrap in list(), because QuerySet is not JSON serializable
    return JsonResponse(data, safe=False)  # or JsonResponse({'data': data})

Or another approach with Django's built-in serializers:

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

def some_view(request):
    qs = SomeModel.objects.all()
    qs_json = serializers.serialize('json', qs)
    return HttpResponse(qs_json, content_type='application/json')

In this case result is slightly different (without indent by default):

[
    {
        "model": "some_app.some_model",
        "pk": 1,
        "fields": {
            "name": "Elon",
            "age": 48,
            ...
        }
    },
    ...
]

I have to say, it is good practice to use something like marshmallow to serialize queryset.

...and a few notes for better performance:

  • use pagination if your queryset is big;
  • use objects.values() to specify list of required fields to avoid serialization and sending to client unnecessary model's fields (you also can pass fields to serializers.serialize);

Solution 2:

It didn't work, because QuerySets are not JSON serializable.

1) In case of json.dumps you have to explicitely convert your QuerySet to JSON serializable objects:

class Model(model.Model):
    def as_dict(self):
        return {
            "id": self.id,
            # other stuff
        }

And the serialization:

dictionaries = [ obj.as_dict() for obj in self.get_queryset() ]
return HttpResponse(json.dumps({"data": dictionaries}), content_type='application/json')

2) In case of serializers. Serializers accept either JSON serializable object or QuerySet, but a dictionary containing a QuerySet is neither. Try this:

serializers.serialize("json", self.get_queryset())

Read more about it here:

https://docs.djangoproject.com/en/dev/topics/serialization/

Solution 3:

For a efficient solution, you can use .values() function to get a list of dict objects and then dump it to json response by using i.e. JsonResponse (remember to set safe=False).

Once you have your desired queryset object, transform it to JSON response like this:

...
data = list(queryset.values())
return JsonResponse(data, safe=False)

You can specify field names in .values() function in order to return only wanted fields (the example above will return all model fields in json objects).

Solution 4:

To return the queryset you retrieved with queryset = Users.objects.all(), you first need to serialize them.

Serialization is the process of converting one data structure to another. Using Class-Based Views, you could return JSON like this.

from django.core.serializers import serialize
from django.http import JsonResponse
from django.views.generic import View

class JSONListView(View):
    def get(self, request, *args, **kwargs):
        qs = User.objects.all()
        data = serialize("json", qs)
        return JsonResponse(data)

This will output a list of JSON. For more detail on how this works, check out my blog article How to return a JSON Response with Django. It goes into more detail on how you would go about this.

Solution 5:

If the goal is to build an API that allow you to access your models in JSON format I recommend you to use the django-restframework that is an enormously popular package within the Django community to achieve this type of tasks.

  • Django Rest Framework Website
  • Github

It include useful features such as Pagination, Defining Serializers, Nested models/relations and more. Even if you only want to do minor Javascript tasks and Ajax calls I would still suggest you to build a proper API using the Django Rest Framework instead of manually defining the JSON response.