Convert a QuerySet to a JSON in Django

  1. Convert a QuerySet to a JSON Using a Custom Method
  2. Convert a QuerySet to a JSON Using Django’s Built-In Serializers
  3. Convert a QuerySet to a JSON Using the values() Function

In Django, all the model managers return a QuerySet when some query is applied over a model. A QuerySet can easily be used in Python and Django’s templating language. We can perform many actions over a QuerySet to fetch the desired results or records. But a QuerySet has a drawback: they are not JSON serializable.

Apart from web applications, Django is also used to make APIs, and in APIs, JSON is essential because data travels in a JSON format between the server and the client.

Although it is not directly possible to convert a QuerySet to JSON, we can use a QuerySet to create a Python object or a stringified JSON. There are a couple of ways to achieve it. This article will discuss some best ways to convert a QuerySet to a JSON.

Convert a QuerySet to a JSON Using a Custom Method

Suppose we have a Django model as follows. We can write a function that will accept an object of this model and return a dictionary representation of the object.

from django.db import models

class Person(models.Model):
    username = models.CharField(max_length = 200, unique = True)
    firstName = models.CharField(max_length = 200)
    middleName = models.CharField(max_length = 200)
    lastName = models.CharField(max_length = 200)
    age = models.IntegerField(default = 0)

And the method to handle the conversion is as follows.

def personToDictionary(person):
    if person == None:
        return None

    dictionary = {}
    dictionary["username"] = person.username
    dictionary["firstName"] = person.firstName
    dictionary["middleName"] = person.middleName
    dictionary["lastName"] = person.lastName
    dictionary["age"] = person.age

    return dictionary

person = Person.objects.get(id = 25)
personDictionary = personToDictionary(person)

This approach gives us more control over the data we wish to include in the dictionary representation. For example, if we had foreign keys, we could include various information of the referenced models. We can also carry out some computations and include them in the dictionary.

Convert a QuerySet to a JSON Using Django’s Built-In Serializers

Django has built-in serializers that can be used to convert models to the desired form. One can transform a model to a JSON, XML, JSONL, and YAML format using serializers. Some of the formats require some additional python libraries to work.

Suppose we have to convert the Person model above to a JSON format. To do so, we would do the following.

from django.core import serializers

person = serializers.serialize("json", Person.objects.get(id = 25))
people = serializers.serialize("json", Person.objects.all())

A serializer can convert a single model as well as a QuerySet. The person and the people variable will now contain the data in a JSON format.

Let’s say that we have to only convert the name fields of the model. To achieve so, we would do the following.

from django.core import serializers

person = serializers.serialize("json", Person.objects.get(id = 25), fields = ("firstName", "middleName", "lastName"))
people = serializers.serialize("json", Person.objects.all(), fields = ("firstName", "middleName", "lastName"))

We have to set the fields parameter to a tuple of field names of the model. One key point to note here is that the primary key, the id, is always serialized, whether you mention it or not.

To learn more about serializers, refer to Django’s official documentation here.

Convert a QuerySet to a JSON Using the values() Function

The third approach uses the values() method that can be called over a QuerySet. A QuerySet returns a set of model instances, while the values() method returns a set of dictionaries representing model instances.

Refer to the following code.

person = Person.objects.filter(age = 25).values()
people = Person.objects.all().values()

By default, a dictionary contains all the fields of the table. If we have to limit the fields, we can use the optional positional arguments, *fields, in this method. Refer to the following code snippet.

person = Person.objects.filter(age = 25).values("id", "age", "firstName", "lastName")
people = Person.objects.all().values("id", "firstName")
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.