Django Rest Framework Serialization Tutorial Part 1

Requirements

I will be assuming that the reader has been following along with the previous tutorial Django Rest Framework Setup.

Objective

By the end of this tutorial you will know how to serialize and deserialize data to be used for retrieving and submitting data into the data_entry app.

Steps

  • Create a serializer class
from rest_framework import serializers
from .models import DataRow
from .choices import GENDER_CHOICES

class DataRowSerializers(serializers.Serializer):
id = serializers.IntegerField(read_only = True)
date = serializers.DateField(required=False)
gender = serializers.ChoiceField(required=False, allow_blank=True, choices=GENDER_CHOICES)
favorite_number = serializers.IntegerField(required=False)

def create(self, validated_data):
"""
Create and return a new 'DataRow' instance given the validated data.
"""
return DataRow.objects.create(**validated_data)

def update(self, instance, validated_data):
"""
Update and return a existing 'DataRow' instance, given the validated data.
"""
instance.date = validated_data.get('date', instance.date)
instance.gender = validated_data.get('gender', instance.gender)
instance.favorite_number = validated_data.get('favorite_number', instance.favorite_number)
instance.save()
return instance

Note: Can save some lines of code by subclassing the ModelSerializer class. Keep reading on to find out how.

  • Lets test this class out by serializing and deserializing some data.
  • Open a bash terminal into the web container.
  • Open a django shell via python manage.py shell
  • Execute the following commands:
from dockerdjango.apps.data_entry.models import DataRow
from dockerdjango.apps.data_entry.serializers import DataRowSerializers 
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

dr = DataRow(date='2017-02-06',gender='M',favorite_number=123) dr.save()

serializer = DataRowSerializers(dr) serializer.data
# {'date': '2017-02-06', 'gender': 'M', 'favorite_number': 123, 'id': 3} Note that the id value may be different depending on whether you have existing entries in the DataRow table in the database previously.

We have now transferred the model instance into native python data type. To complete the serialization process we render the data into JSON format.

content = JSONRenderer().render(serializer.data)
content
# '{"id":3,"date":"2017-02-06","gender":"M","favorite_number":123}'
NOTE: you may get a different id value.

Deserialization follows a similar process but in reverse. First we convert the content data into python native data type.

from django.utils.six import BytesIO
dstream = BytesIO(content)
data=JSONParser().parse(dstream)
data
# {u'date': u'2017-02-06', u'gender': u'M', u'favorite_number': 123, u'id': 3}
NOTE: you may get a different id value.
type(data)
# <type 'dict'>

You can now create a model instance from the data object that you just deserialized.

datarow = DataRowSerializers(data=data)
datarow.is_valid()
# True
datarow.validated_data
# OrderedDict([(u'date', datetime.date(2017, 2, 6)), (u'gender', 'M'), (u'favorite_number', 123)])
datarow.save()
# <DataRow: DataRow object>

You have now saved a new model instance into your database.

You can also serialize querysets instead of single model instances (which will be very useful when wanting to GET or PUT large quantities of data.

datarows = DataRowSerializers(DataRow.objects.all(), many=True)
datarows.data
# [OrderedDict([('id', 3), ('date', '2017-02-06'), ('gender', 'M'), ('favorite_number', 123)]), OrderedDict([('id', 4), ('date', '2017-02-06'), ('gender', 'M'), ('favorite_number', 123)])]
NOTE: notice that two entries with the same data (different id) was retrieved.

Now lets see how we can make use of the ModelSerializers class to refactor some of the code.

  • Open the serializers.py file created earlier and replace the DataRowSerializers class with the following code:
class DataRowSerializers(serializers.ModelSerializer):
class Meta:
model = DataRow
fields = ('id', 'date', 'gender', 'favorite_number')

My inheriting the ModelSerializer class a simple default create and update method for the DataRowSerializers class has been inherited.

  • You can confirm that you can still serialize and deserialize data from the django shell using the same snippet of code above (try using different data this time and see what happens).
  • With serializers you can inspect all the fields of the serializer by printing its representation. Open a django shell and run the following lines of code.
from dockerdjango.apps.data_entry.serializers import DataRowSerializers
serializer = DataRowSerializers()
print(repr(serializer))
# DataRowSerializers():
id = IntegerField(read_only=True)
date = DateField(required=False)
gender = ChoiceField(allow_blank=True, choices=(('M', 'Male'), ('F', 'Female')), required=False)
favorite_number = IntegerField(required=False)

Conclusion

You have now completed part 1 of the Django Rest Framework Serialization tutorial. In the next tutorial we will explore how we can write some API views using the serializer classes just created and make a first attempt at a WEB API. You can find the tutorial here Django Rest Framework Serialization Tutorial Part 2

Subscribe to our mailing list

* indicates required