Working with Serializers

Before we go any further we'll familiarize ourselves with using our new Serializer class. Let's drop into the Django shell.

  1. python manage.py shell

Okay, once we've got a few imports out of the way, let's create a couple of code snippets to work with.

  1. from snippets.models import Snippet
  2. from snippets.serializers import SnippetSerializer
  3. from rest_framework.renderers import JSONRenderer
  4. from rest_framework.parsers import JSONParser
  5. snippet = Snippet(code='foo = "bar"\n')
  6. snippet.save()
  7. snippet = Snippet(code='print("hello, world")\n')
  8. snippet.save()

We've now got a few snippet instances to play with. Let's take a look at serializing one of those instances.

  1. serializer = SnippetSerializer(snippet)
  2. serializer.data
  3. # {'id': 2, 'title': '', 'code': 'print("hello, world")\n', 'linenos': False, 'language': 'python', 'style': 'friendly'}

At this point we've translated the model instance into Python native datatypes. To finalize the serialization process we render the data into json.

  1. content = JSONRenderer().render(serializer.data)
  2. content
  3. # b'{"id": 2, "title": "", "code": "print(\\"hello, world\\")\\n", "linenos": false, "language": "python", "style": "friendly"}'

Deserialization is similar. First we parse a stream into Python native datatypes…

  1. import io
  2. stream = io.BytesIO(content)
  3. data = JSONParser().parse(stream)

…then we restore those native datatypes into a fully populated object instance.

  1. serializer = SnippetSerializer(data=data)
  2. serializer.is_valid()
  3. # True
  4. serializer.validated_data
  5. # OrderedDict([('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
  6. serializer.save()
  7. # <Snippet: Snippet object>

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.

We can also serialize querysets instead of model instances. To do so we simply add a many=True flag to the serializer arguments.

  1. serializer = SnippetSerializer(Snippet.objects.all(), many=True)
  2. serializer.data
  3. # [OrderedDict([('id', 1), ('title', ''), ('code', 'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello, world")\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', ''), ('code', 'print("hello, world")'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]