DRF Serialization II

Posted under » Django on 29 Sep 2021

This is the official tutorial from DRF regarding serialization which I am trying out. This tutorial will cover creating a simple pastebin code highlighting Web API.

For this I will have to install pygments for the code highlighting.

$ pip install pygments

In our 1st tutorial we have created the napi app but we shall create another new app (snippets) that we'll use to create a simple Web API.

$ python manage.py startapp snippets

We proceed with creating the snippets model

from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles

LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted([(item, item) for item in get_all_styles()])

class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)

    class Meta:
	ordering = ['created']

After making sure the settings file is uploaded as well, we proceed to migrate.

Here how the serializers.py will look like.

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES

class SnippetSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    code = serializers.CharField(style={'base_template': 'textarea.html'})
    linenos = serializers.BooleanField(required=False)
    language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
    style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')

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

    def update(self, instance, validated_data):
        """
        Update and return an existing `Snippet` instance, given the validated data.
        """
        instance.title = validated_data.get('title', instance.title)
        instance.code = validated_data.get('code', instance.code)
        instance.linenos = validated_data.get('linenos', instance.linenos)
        instance.language = validated_data.get('language', instance.language)
        instance.style = validated_data.get('style', instance.style)
        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.

To save space, you can read about using the shell with this SnippetSerializer class.

In the 1st DRF serialization tutorial, we have used the HyperlinkedModelSerializer, let us look at ModelSerializer class.

class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
      model = Snippet
      fields = ['id', 'title', 'code', 'linenos', 'language', 'style']

One nice property that serializers have is that you can inspect all the fields in a serializer instance, by printing its representation. ModelSerializer classes are simply a shortcut for creating serializer classes:

Even if the serializers.py appears shorter, it works as well as the longer version at the beginning of this tutorial. Of course we need to have the views.py which is on the next page.

web security linux ubuntu python django git Raspberry apache mysql php drupal cake javascript css AWS