Serializer
Serializer
The first thing we need to get started on our Web API is to provide a way of
serializing and deserializing the snippet instances into representations such
as json . We can do this by declaring serializers that work very similar to
Django's forms. Create a file in the snippets directory
named serializers.py and add the following.
class SnippetSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
linenos = serializers.BooleanField(required=False)
"""
Create and return a new `Snippet` instance, given the validated data.
"""
return Snippet.objects.create(**validated_data)
"""
Update and return an existing `Snippet` instance, given the validated data.
"""
instance.save()
return instance
The first part of the serializer class defines the fields that get
serialized/deserialized. The create() and update() methods define how fully
fledged instances are created or modified when calling serializer.save()
A serializer class is very similar to a Django Form class, and includes similar
validation flags on the various fields, such
as required , max_length and default .
The field flags can also control how the serializer should be displayed in certain
circumstances, such as when rendering to HTML. The {'base_template':
'textarea.html'} flag above is equivalent to using widget=widgets.Textarea on a
Django Form class. This is particularly useful for controlling how the browsable
API should be displayed, as we'll see later in the tutorial.
We can actually also save ourselves some time by using
the ModelSerializer class, as we'll see later, but for now we'll keep our
serializer definition explicit.
Okay, once we've got a few imports out of the way, let's create a couple of code
snippets to work with.
snippet.save()
snippet.save()
We've now got a few snippet instances to play with. Let's take a look at
serializing one of those instances.
serializer = SnippetSerializer(snippet)
serializer.data
At this point we've translated the model instance into Python native datatypes.
To finalize the serialization process we render the data into json .
content = JSONRenderer().render(serializer.data)
content
import io
stream = io.BytesIO(content)
data = JSONParser().parse(stream)
...then we restore those native datatypes into a fully populated object instance.
serializer = SnippetSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# OrderedDict([('title', ''), ('code', 'print("hello, world")\n'), ('linenos',
False), ('language', 'python'), ('style', 'friendly')])
serializer.save()
Notice how similar the API is to working with forms. The similarity should
become even more apparent when we start writing views that use our serializer.
serializer.data
Using ModelSerializers
Our SnippetSerializer class is replicating a lot of information that's also
contained in the Snippet model. It would be nice if we could keep our code a bit
more concise.
Let's look at refactoring our serializer using the ModelSerializer class. Open the
file snippets/serializers.py again, and replace the SnippetSerializer class with
the following.
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
One nice property that serializers have is that you can inspect all the fields in a
serializer instance, by printing its representation. Open the Django shell
with python manage.py shell , then try the following:
serializer = SnippetSerializer()
print(repr(serializer))
# SnippetSerializer():
# id = IntegerField(label='ID', read_only=True)
# linenos = BooleanField(required=False)