Search Here

How to serializer models in Django Framework with many different ways

For serialization, Python has JSON Module. But it is not easy to serialize complex Django objects into JSON or any other format. But in this post, You’ll learn different possible ways of serializing Django objects into a dictionary or JSON.

Creating custom method in the model

Let us create a class model called PostModel in posts/models.py. We’ll be using this model as an example to show the working of Django object serialization.

from django.db import models

class PostModel( models.Model ):
    post_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    content = models.TextField(null=True)
    is_active = models.IntegerField(default=1)

1. Using the model_to_dict function from Django forms

The function model_to_dict gets all the model fields and converts the model instance to a dictionary then which can be used to serializer in any format.
This method is provided by Django which can be imported using from django.forms.models import model_to_dict.

from posts.models import PostModel
from rest_framework.response import Response
from django.forms.models import model_to_dict

def show(request, id):
    post = PostModel.objects.get(pk=pk) #post instance
    
    post_dictionary = model_to_dict(post) #converts post instance to dictionary

    return Response(post_dictionary) # returns json

Note

The model_to_dict function ignores DateTime fields while converting to the dictionary only if auto_now or auto_now_add parameters are provided to those model fields.
It basically checks it the fields are editable before converting to a dictionary.

2. Using the Django serialize method

The alternative to Python Json Module is the serializer function provided by Django Framework.

from django.core import serializers

def show(request, id):
    json_serialized = serializers.serialize("json", PostModel.objects.all())
    
    return json_serialized

The advantage of using this function is that you can serialize it into XML, YAML, and jsonl formats.

serializers.serialize("xml", PostModel.objects.all())
serializers.serialize("yaml", PostModel.objects.all())
serializers.serialize("jsonl", PostModel.objects.all())

Caution

When passed instance instead to list of queryset. It will throw object is not iterable using serializers.serialize. The issue can be resolved by using the below examples.

        serializers.serialize("json", PostModel.objects.filter(pk=pk))
        #OR
        serializers.serialize("json", [PostModel.objects.get(pk=pk)])

Go to the documentation of Serialization in Django Framework.

3. Creating a Custom JSON Encoder for Models

You can create a custom JSON encoder that can serialize model instances and also other types of data. We’ll be using JSON models.

The json.dumps method has a parameter cls which takes a class the does serializer using that class.

Creating a Custom Encoder for Models using json.JSONEncoder class

In views.py

from json import JSONEncoder

class BaseModelJSONEncoder(JSONEncoder):

    def default(self, o):
        
        try:
            if isinstance(o, models.Model):
                return model_to_dict(o) #converts models instance to dictionary
            elif isinstance(o, models.query.QuerySet):
                return [ model_to_dict(obj) for obj in o ] #converts models list queryset to dictionary
            else:
                iterable = iter(o)
        except TypeError:
            pass
        else:
            return list(iterable)

        return JSONEncoder.default(self, o)

def show(request, id):
    return HttpResponse(json.dumps(PostModel.objects.all(), cls=BaseModelJSONEncoder))

The class BaseModelJSONEncoder will convert the instance to the dictionary and returns JSON. The BaseModelJSONEncoder.default() method must be overridden and specify custom serialization logic within default() method.

4. Using ModelSerializer from Django RestFramework

Another way is to install rest_framework which as has a ModelSerializer class that makes serialization of models very easier.

We have a post that will teach you to create a custom serializer.
In posts\serializers.py

from posts.models import PostModel
from rest_framework import serializers

class PostSerializer( serializers.ModelSerializer ):
    class Meta:
        model = PostModel
        fields = '__all__'

In posts\views.py

from posts.serializers import PostSerializer
from posts.models import PostModel
from rest_framework.response import Response

def show(request, id):
    serializer = PostSerializer(PostModel.objects.get(pk=pk))
    return Response(serializer.data)

Watch Video

Go to the documentation of Django Framework ModelSerializer Class.