Django REST Framework: understanging ModelSerializer

By Dimitri Denisjonok | Code

We use Django REST Framework at to create REST-full APIs. One of the most used features is serializers. I recently worked on a project where I had to use serializers a lot. It took me some time to figure out how they work and what the flow should be when using them. The purpose of this post is to share lessons learned.

First, terminology.
Deserialization - converting JSON to Django Model Instance.
Serialization - is the reverse, converting Django Model Instance to JSON.

Typically, there are 2 things we want to do :
1) Take user input, process it and save to database (deserialization)
2) Present data from our database to the user (serialization)

Now, let's look how DRF and ModelSerializer, in particular, can help us with this task.

Creating your serializer

First, you want to define class Meta:

class Meta:
model = YourModel
fields = (

That's the bare minimum. You can also add read_only_fields, required_fields, etc.

If you need object-level, custom validation, then override the validate() method.
Also, you may want to define your custom save(), create(), update().


Once you initialize the serializer object, you'll want to call .is_valid().
This will make the following attributes and methods available to you:
- .validated_data
- .errors
- .data
- .save()

Here's the flow:

s = serializer(data=data)
if s.is_valid(): # will call .create()
return s.errors


2 cases:

  1. Present data from database:
    s = serializer(instance=instance) # returns json representation
  2. Update data in database (NOTE: in this case data is required)
    s = serializer(instance=instance, data=data)
    if s.is_valid(): # will call .update()
        return s.errors

Note on context

When initialising a serializer, optionally, you can pass in context dict. You then can access data from the context from any method you define on your serializer using self.context.

For example:

s = serializer(data=data, context={'user': request.user})

And your serializer create() method may look something like this:

def create(self, validated_data):
return YourModel.objects.create(user=self.context.get('user'), **validated_data)

 Check out my gist for more detailed code examples.

Post a comment
listings__registration-popup__header-smaller Get our free insider house sitting e-guide highlights - and free access to search house sits

As Featured In...