Building a Powerful Serializer with The Django Python Web Framework
By: Pink Academy
Tags: Python Programming, Django, Python3, Django Rest Framework, Web Development

Django comes with a serialization module that allows you to “translate” Models into other formats:

from django.core import serializers serializers.serialize('json', Order.objects.all())

It covers the most-used cases for web applications, such as JSON, YAML, and XML. But you can also use third-party serializers or create your own. You just need to register it in your settings.py file:

# settings.py

SERIALIZATION_MODULES = {

'my_format': appname.serializers.MyFormatSerializer,

}

To create your own MyFormatSerializer , you need to implement the .serialize() method and accept a queryset and extra options as params:

class MyFormatSerializer:

def serialize(self, queryset, **options):

# serious serialization happening

Now you can serialize your queryset to your new format:

from django.core import serializers serializers.serialize('my_format', Order.objects.all())

You can use the options parameters to define the behavior of your serializer. For example, if you want to define that you’re going to work with nested serialization when dealing with ForeignKeys or you just want that data to return its primary keys, you can pass a flat=True param as an option and deal with that within your method:

class MyFormatSerializer:

def serializer(self, queryset, **options):

if options.get('flat', False):

# don't recursively serialize relationships

# recursively serialize relationships

One way to use Django serialization is with the loaddata and dumpdata management commands.

DRF serializers

In the Django community, the Django REST framework (DRF) offers the best-known serializers. Although you can use Django’s serializers to build the JSON you’ll respond to in your API, the one from the REST framework comes with nice features that help you deal with and easily validate complex data.

In the Order example, you could create a serializer like this:

from restframework import serializers class OrderSerializer(serializers.Serializer):

product = serializers.CharField(max_length=255)

customer = serializers.CharField(max_lenght=255)

price = serializers.DecimalField(max_digits=5, decimal_places=2)

date = serializers.DateField()

And easily serialize its data:

order = Order('pen', 'renato', 10.50, date.today())

serializer = OrderSerializer(order) serializer.data

# {'product': 'pen', 'customer': 'renato', 'price': '10.50', 'date': '2020-08-16'}

To be able to return an instance from data, you need to implement two methods — create and update:

from rest_framework import serializers class OrderSerializer(serializers.Serializer):

product = serializers.CharField(max_length=255)

customer = serializers.CharField(max_length=255)

price = serializers.DecimalField(max_digits=5, decimal_places=2)

date = serializers.DateField() def create(self, validated_data):

# perform order creation

return order def update(self, instance, validated_data):

# perform instance update

return instance

After that, you can create or update instances by calling is_valid() to validate the data and save() to create or update an instance:

serializer = OrderSerializer(**data)

## to validate data, mandatory before calling save

serializer.is_valid()

serializer.save()

Model serializers

When serializing data, you often need to do it from a database, therefore, from your models. A ModelSerializer, like a ModelForm, provides an API to create serializers from your models. Suppose you have an Order model:

from django.db import models

class Order(models.Model):

product = models.CharField(max_length=255)

customer = models.CharField(max_length=255)

price = models.DecimalField(max_digits=5, decimal_places=2)

date = models.DateField()

You can create a serializer for it like this:

from rest_framework import serializers

class OrderSerializer(serializers.ModelSerializer):

class Meta:

model = Order

fields = '__all__'

Django automatically includes all model fields in the serializer and creates the create and update methods.

Using serializers in class-based views (CBVs)

Like Forms with Django’s CBVs, serializers integrate well with DRFs. You can set the serializer_class attribute so that the serializer will be available to the view:

from rest_framework import generics

class OrderListCreateAPIView(generics.ListCreateAPIView):

queryset = Order.objects.all()

serializer_class = OrderSerializer

You can also define the get_serializer_class() method:

from rest_framework import generics

class OrderListCreateAPIView(generics.ListCreateAPIView):

queryset = Order.objects.all()



def get_serializer_class(self):

if is_free_order():

return FreeOrderSerializer

return OrderSerializer

There are other methods in CBVs that interact with serializers. For example, get_serializer() returns an already-instantiated serializer, while get_serializer_context() returns the arguments you’ll pass to the serializer when creating its instance. For views that create or update data, there are create and update that validate the data with the is_valid method to be saved, and perform_create and perform_update that call the serializer's save method.

Reference links:

Other Recommended Articles from The Programming Hub: