Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django DRF - What's the use of serializers?

I've been using Django for over 3 years now, but have never felt the need to use DRF. However, seeing the growing popularity of DRF, I thought of giving it a try.

Serializing is the concept I find it most difficult. Consider for eg:- I want to save user details. Following is the user related models.

class Users(models.Model):
    GENDER_CHOICES = (
        ('M', 'MALE'),
        ('F', 'FEMALE'),
        ('O', 'OTHERS'),
    )
    first_name = models.CharField(max_length=255, blank=True, null=True)
    middle_name = models.CharField(max_length=255, blank=True, null=True)
    last_name = models.CharField(max_length=255, blank=True, null=True)
    gender = models.CharField(choices=GENDER_CHOICES, max_length=1, blank=True,
                              null=True)


class UserAddress(models.Model):
    ADDRESS_TYPE_CHOICES = (
        ('P', 'Permanent'),
        ('Cu', 'Current'),
        ('Co', 'Correspondence')
    )
    line1 = models.CharField(max_length=255)
    line2 = models.CharField(max_length=255, blank=True, null=True)
    pincode = models.IntegerField()
    address_type = models.CharField(choices=ADDRESS_TYPE_CHOICES,
                                    max_length=255)
    user_id = models.ForeignKey(Users, related_name='uaddress')


class UserPhone(models.Model):
    phone = models.CharField(max_length=10)
    user_id = models.ForeignKey(Users, related_name='uphone')


class UserPastProfession(models.Model):
    profession = models.CharField(max_length=10)  # BusinessMan, software Engineer, Artist etc.
    user_id = models.ForeignKey(Users, related_name='uprofession')

I'm getting all the user details bundled in one POST endpoint.

{
    'first_name': 'first_name',
    'middle_name': 'middle_name',
    'last_name': 'last_name',
    'gender': 'gender',
    'address': [{
        'line1': 'line1',
        'line2': 'line2',
        'address_type': 'address_type',
    }],
    'phone': ['phone1', 'phone2'],
    'profession': ['BusinessMan', 'Software Engineer', 'Artist']
}

Without using DRF, I would have made a Users object first, linking it with UserAddress, UserPhone and UserPastProfession object.

How the same could be done using DRF? I mean validating, serializing, and then saving the details. How serializers.py file will be look like?

like image 813
PythonEnthusiast Avatar asked Oct 21 '17 07:10

PythonEnthusiast


People also ask

What are Serializers in Python?

Last Updated on June 21, 2022. Serialization refers to the process of converting a data object (e.g., Python objects, Tensorflow models) into a format that allows us to store or transmit the data and then recreate the object when needed using the reverse process of deserialization.

When would you use a serializer?

Serialization is the process of transforming data into a format that can be stored or transmitted and then reconstructing it. It's used all the time when developing applications or storing data in databases, in memory, or converting it into files.

What are Serializers explain Modelserializers?

The ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields. The ModelSerializer class is the same as a regular Serializer class, except that: It will automatically generate a set of fields for you, based on the model.

What does serializer save () do?

serializer. save() calls def save() method in the serializer. save() method in the serializer will call either def update() or def create() methods in the serializer.


1 Answers

If you want to make your life easy, you will surely use it.

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

This gives you a generic way to control the output of your responses, as well as a ModelSerializer class which provides a useful shortcut for creating serializers that deal with model instances and querysets.

They save you from writing a lot of custom code. Let’s look at some examples.

Pretend we have an app that tracks a list of tasks that the user has to complete by a certain date. The Task model might look something like the following:

class Task(models.Model):
    title = models.CharField(max_length=255)
    due_date = models.DateField() 
    completed = models.BooleanField(default=False)

When the user requests those tasks, our app returns a response in the form of a JSON-serialized string. What happens when we try to serialize our Django objects using the built-in json library?

import json
task = Task.objects.first()
json.dumps(task)

We get a TypeError. Task is not JSON serializable. To bypass this, we have to explicitly create a dictionary with each of the attributes from Task.

json.dumps({
    'title': task.title,
    'due_date': task.due_date.strftime('%Y-%m-%d'),
    'completed': task.completed
}) 

Serializing a Python object from a JSON string or from request data is just as painful.

from datetime import datetime 
title = request.data.get('title')
due_date = datetime.strptime(request.data.get('due_date'), '%Y-%m-%d').date()
completed = request.data.get('completed')
task = Task.objects.create(title=title, due_date=due_date, completed=completed) 

Now, imagine having to follow these steps in multiple views if you have more than one API that needs to serialize (or deserialize) JSON data. Also, if your Django model changes, you have to track down and edit all of the custom serialization code.

Creating and using a serializer is easy:

from rest_framework import serializers 
class TaskSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        return Task.objects.create(**validated_data)

    class Meta:
        model = Task
        fields = ('title', 'due_date', 'completed')

# Serialize Python object to JSON string. 
task_data = TaskSerializer(task).data 

# Create Python object from JSON string.
task_data = TaskSerializer(request.data)
task = task_data.create() 

If you update the Django model, you only have to update the serializer in one place and all of the code that depends on it works. You also get a lot of other goodies including (as you mentioned) data validation.

Hope that helps!

like image 78
Syed Faizan Avatar answered Sep 30 '22 09:09

Syed Faizan