Django Rest Framework Serializers - Panduan Lengkap
1. Dasar Serializer
Serializer Dasar
# serializers.py
from rest_framework import serializers
class ProductSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
price = serializers.DecimalField(max_digits=10, decimal_places=2)
description = serializers.CharField(required=False)
def create(self, validated_data):
return Product.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.price = validated_data.get('price', instance.price)
instance.description = validated_data.get('description', instance.description)
instance.save()
return instance
ModelSerializer
# serializers.py
from rest_framework import serializers
from .models import Product
class ProductModelSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['name', 'price', 'description']
# atau gunakan fields = '__all__' untuk semua field
2. Tipe Field Serializer
Text Fields
# Field untuk data teks
name = serializers.CharField(
max_length=100,
required=True,
allow_blank=False
)
description = serializers.CharField(
style={'base_template': 'textarea.html'}
)
email = serializers.EmailField()
Number Fields
# Field untuk angka
price = serializers.DecimalField(
max_digits=10,
decimal_places=2,
min_value=0
)
quantity = serializers.IntegerField(min_value=1)
rating = serializers.FloatField(min_value=0, max_value=5)
Relational Fields
# Field untuk relasi
category = serializers.PrimaryKeyRelatedField(queryset=Category.objects.all())
tags = serializers.StringRelatedField(many=True)
owner = serializers.HyperlinkedRelatedField(
view_name='user-detail',
read_only=True
)
3. Validasi Serializer
Validasi di Level Field
class ProductSerializer(serializers.ModelSerializer):
def validate_name(self, value):
if value.isdigit():
raise serializers.ValidationError(
'Nama tidak boleh berupa angka'
)
return value
Validasi Serializer Level
class ProductSerializer(serializers.ModelSerializer):
def validate(self, data):
if data['discount_price'] >= data['price']:
raise serializers.ValidationError(
'Harga diskon harus lebih kecil dari harga asli'
)
return data
4. Penggunaan di Views
Function Based Views
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['POST'])
def product_create(request):
serializer = ProductSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
Class Based Views
from rest_framework import generics
class ProductCreateAPIView(generics.CreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
5. Nested Serializer
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name']
class ProductSerializer(serializers.ModelSerializer):
category = CategorySerializer()
class Meta:
model = Product
fields = ['id', 'name', 'price', 'category']
6. Tips Penggunaan Serializer
- Custom Field
class ProductSerializer(serializers.ModelSerializer):
discount_percentage = serializers.SerializerMethodField()
def get_discount_percentage(self, obj):
return ((obj.price - obj.discount_price) / obj.price) * 100
- Read Only Fields
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
read_only_fields = ['created_at', 'updated_at']
- Dynamic Fields
class DynamicProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
def __init__(self, *args, **kwargs):
fields = kwargs.pop('fields', None)
super().__init__(*args, **kwargs)
if fields:
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)