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.