Implementing Serializers in Django REST Framework
Django REST framework serializers are defined as classes that inherit from rest_framework.serializers.Serializer. For example, given a dataabse model Book:
class Book(models.Model):
title = models.CharField(max_length=50, verbose_name='Title')
pub_date = models.DateField(verbose_name='Publication Date', null=True)
reads = models.IntegerField(default=0, verbose_name='Read Count')
comments = models.IntegerField(default=0, verbose_name='Comment Count')
cover = models.ImageField(upload_to='covers', verbose_name='Cover Image', null=True)
We can create a corresponding serializer:
class BookSerializer(serializers.Serializer):
"""Book data serializer"""
id = serializers.IntegerField(label='ID', read_only=True)
title = serializers.CharField(label='Title', max_length=50)
pub_date = serializers.DateField(label='Publication Date', required=False)
reads = serializers.IntegerField(label='Read Count', required=False)
comments = serializers.IntegerField(label='Comment Count', required=False)
cover = serializers.ImageField(label='Cover Image', required=False)
Field Types and Options
Common field types include:
BooleanField,CharField,EmailFieldIntegerField,FloatField,DecimalFieldDateTimeField,DateField,TimeFieldFileField,ImageFieldListField,DictField
Field options include:
max_length,min_lengthallow_blank,trim_whitespacemax_value,min_valueread_only,write_onlyrequired,default
Creating Serializer Objects
Serializer constructor:
Serializer(instance=None, data=empty, **kwargs)
Example usage:
book = Book.objects.get(id=1)
serializer = BookSerializer(book)
serializer.data
For querysets:
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
serializer.data
Related Object Nesting
Several approaches for handling related objects:
- PrimaryKeyRelatedField:
publisher = serializers.PrimaryKeyRelatedField(queryset=Publisher.objects.all())
- StringRelatedField:
publisher = serializers.StringRelatedField()
- Nested serializers:
publisher = PublisherSerializer()
Deserialization and Validation
Validation methods:
- Field-level validation:
def validate_title(self, value):
if 'django' not in value.lower():
raise serializers.ValidationError("Book must be about Django")
return value
- Object-level validatino:
def validate(self, data):
if data['reads'] < data['comments']:
raise serializers.ValidationError("Read count cannot be less than comments")
return data
- Validators:
def about_django(value):
if 'django' not in value.lower():
raise serializers.ValidationError("Book must be about Django")
class BookSerializer(serializers.Serializer):
title = serializers.CharField(validators=[about_django])
ModelSerializer
Automaticlaly generates serializers from models:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
Customization options:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('id', 'title', 'pub_date')
read_only_fields = ('id',)
extra_kwargs = {
'reads': {'min_value': 0},
'comments': {'min_value': 0}
}