Introduction To Serializers
In DjangoRestFramework , Serializers are responsible for converting complex data such querysets and model instance to native python datatypes(called serialization) that can be easily rendered into JSON,XML or other content type which is understandable by frontend.
It convert complex data to python native data types then it is easy to convert python data to JSON easily.
Serializers are also responsible for deserialization which means it allows parsed data to be converted back into complex types , after first validating the incomimg data.
Hence main concept of DRF are
1.Serialization
2.Deserializers
1.Serialization
For the serialization , ypou first have to make serializer class
Serializer class
A serializer class is very similar to django form and modelform class and includes similar validation flags on the various fields, such as required,max-length,default,read_only and many more. DRF provides a serializerclass which gives you a powerful,generic way to control the output of your response, as well as modelserializer class which provides a useful shortcut for creating serializers that deals with model instance and the querysets.
How to create the serializer class
1.create the separate serializers.py file to write all serializer(it is optional but it is good pratice to make separate file)
2.Import serializers nad make the serializer class like below
# serializers.py
from rest_framework import serializers
class EmployeeSerializers(serializers.Serializer):
uuid=serializers.CharField(read_only=True)
name=serializers.CharField(max_length=255)
age=serializers.CharField(max_length=255)
company=serializers.CharField(max_length=255)
Hence process of converting complex data such as queryset and model instances to native python datatypes are called serialization in DRF.
from .models import Employee
from .serializer import EmployeeSerializers
from rest_framework.renderers import JSONRenderer
from django.http import HttpResponse,JsonResponse
def EmployeeList(request):
'''
creating the model instance
'''
stu=Employee.objects.all() #complex data
'''
converting model instance stu to python dict/serializing data in serializer data comes in the form of dictionary which can be in serializer.data
'''
serializer= EmployeeSerializers(stu,many=True) #python data
'''
jsonrender will convert the serializind data into the json formate which is understand by frontend
'''
json_data= JSONRenderer().render(serializer.data) # json formated data
'''using httpresponse json_data is send as a response'''
return HttpResponse(json_data,content_type='application/json')
# return JsonResponse(serializer.data,safe=False)
# write safe=False if data is not in dictionary form
Serializer Fields
serializers Fields handle converting between primitive values and internal datatypes.They also deals with validating input values as well as retriving and setting the values from their parent objects.
syntax: example:
from rest_framework import serializers from rest_framework import serializers
serializers.field_name() serializers.charfield(max-length=255)
some of the serializer filed are listed here after:
1.CharField(max_length=None,min_length=None,alloe_blank=false,trim_whitespace=True)
2.IntegerField(max_value=None,min_value=None)
3.FloatField(max_value=None,min_value=None)
4.DecimalField(max-digits,decimal_places,max_value=None,min_value=None)
5.SlugField(max_length=None,min_length=None,allow_blank=False,trim_whitespace=True)
slugfield is sa regexfield that validate the input against the pattern [a-zA-Z0-9]
6.EmailField()
7.BooleanField()
8.NullBooleanField() - that also accepts None as a vald value
9.URLField()
10.DateField(format=api_settings.DATE_FORMATE,input_format=None)
11.TimeField()
12.DateTimeField()
13.DurationField()
14.UUIDField()
15.FileField(max_length=None,allow_empty_file=False,use_url=UPLOADED_FILES_USE_URL)
16..FileField(max_length=None,allow_empty_file=False,use_url=UPLOADED_FILES_USE_URL)
17.FilePathField()
18.RegexField()
19.ChoiceField()
20.MultipleChoiceField()
21.ListField()
22.DicField()
23.HstoreField()
24.JSONField()
25.ReadOnlyField()
26.HiddenField()
27.ModelField()
28.SerializerMethodField()
Core Argument
1.label -a short text string that may be used as the name of the field in HTML form field or other description elements/serializer filed
2.validator - used in validation
3.error_messages - a dictionary of error codes to error message
4.help_text - just like placeholder
5.required
6.default
7.initial -a value that should be usd for pre populating the value of HTML form fields.
8.read_only
9.write_only
10.allow_null
11.source
12.style -a dictionary of key_value pairs that can be used to control how renders should render the filed
example: password=serializers.CharField(max_length=255,style={'input_type':'password','placeholder';'Password'})
Note:
All other arguments like default,error_messages,required all are written in style={}
Deseialization
Serializer are also responsible for deserialization which means it allows parsed data to be converted back into complex types , after first validating the incoming data.
There are bsically two steps for deserialization.
step-1: creating the serializer object
ser=StudentSerializer(data=parsed_data)
step-2:validate data
ser.is_valid()
if data is validated then the data in the form of dictionary can be found in ser,data where as if there are some error while validating the data then errors will be on ser.errors
#serializer.py
from rest_framework import serializers
from .models import Album
class AlbumSetrializer(serializers.Serializer):
album_name = serializers.CharField(max_length=255)
artist = serializers.CharField(max_length=255)
def create(self, validated_data):
return Album.objects.create(**validated_data)
from django.shortcuts import render
import io
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from .serializers import AlbumSetrializer
from rest_framework import status
from django.views import View
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.http import HttpResponse
@method_decorator(csrf_exempt, name="dispatch")
class AlbumAPIView(View):
def post(self, request, *args, **kwargs):
# get the data from the body
json_data = request.body
# incoming json_dta is converted into stream
stream = io.BytesIO(json_data)
# stream data need to be converted into python data
python_data = JSONParser().parse(stream)
# now converting the python data into the complex data type
serializer = AlbumSetrializer(data=python_data)
# now check the complex data and validate it befor saving it
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is created'}
# this one is python data we need to convert it into json to send
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
CRUD Operation
#serializers.py
from rest_framework import serializers
from .models import Album
class AlbumSetrializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
album_name = serializers.CharField(max_length=255)
artist = serializers.CharField(max_length=255)
def create(self, validated_data):
'''this method is called when post http method is invoked'''
print("post")
return Album.objects.create(**validated_data)
def update(self, instance, validated_data):
'''this method is called when put or patch http method is invoked'''
print(instance) # to get the instance to be updated
print(self.data) # to get the old value
print(validated_data) # get the new data to be updated
instance.album_name = validated_data.get(
"album_name", instance.album_name)
instance.artist = validated_data.get("artist", instance.artist)
instance.save()
return instance
#views.py classbase view
from django.shortcuts import render
import io
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from .serializers import AlbumSetrializer
from rest_framework import status
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.http import HttpResponse, JsonResponse
from .models import Album
@method_decorator(csrf_exempt, name="dispatch")
class AlbumAPIView(View):
def get(self, request):
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
# id = request.GET.get("id", None)
if id is not None:
album = Album.objects.get(id=id)
ser = AlbumSetrializer(album)
# json_data = JSONRenderer().render(ser.data)
# return HttpResponse(json_data, content_type="application/json")
return JsonResponse(ser.data, safe=False, status=status.HTTP_200_OK)
album = Album.objects.all()
ser = AlbumSetrializer(album)
json_data = JSONRenderer().render(ser.data)
return HttpResponse(json_data, content_type="application/json")
def post(self, request, *args, **kwargs):
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
serializer = AlbumSetrializer(data=python_data)
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is created'}
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
def put(self, request, *args, **kwargs):
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
album = Album.objects.get(id=id)
serializer = AlbumSetrializer(album, data=python_data)
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is updated', "data": serializer.data}
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
def patch(self, request, *args, **kwargs):
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
album = Album.objects.get(id=id)
serializer = AlbumSetrializer(album, data=python_data, partial=True)
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is partially updated',
"data": serializer.data}
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
def delete(self, request, *args, **kwargs):
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
album = Album.objects.get(id=id)
album.delete()
json_error = JSONRenderer().render(
{"message": "album is successfully deleted"})
return HttpResponse(json_error, status=status.HTTP_204_NO_CONTENT, content_type='application/json')
#urls.py
path('list/', views.AlbumAPIView.as_view())
function base view
#views.py function base view
import io
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from .serializers import AlbumSetrializer
from rest_framework import status
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse, JsonResponse
from .models import Album
@csrf_exempt
def AlbumAPIView(request):
if request.method == "GET":
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
if id is not None:
album = Album.objects.get(id=id)
ser = AlbumSetrializer(album)
return JsonResponse(ser.data, safe=False, status=status.HTTP_200_OK)
album = Album.objects.all()
ser = AlbumSetrializer(album)
json_data = JSONRenderer().render(ser.data)
return HttpResponse(json_data, content_type="application/json")
if request.method == "POST":
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
serializer = AlbumSetrializer(data=python_data)
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is created'}
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
if request.method == "PUT":
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
album = Album.objects.get(id=id)
serializer = AlbumSetrializer(album, data=python_data)
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is updated', "data": serializer.data}
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
if request.method == "PATCH":
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
album = Album.objects.get(id=id)
serializer = AlbumSetrializer(album, data=python_data, partial=True)
if serializer.is_valid():
serializer.save()
msz = {'messag': 'Album is partially updated',
"data": serializer.data}
json_data = JSONRenderer().render(msz)
return HttpResponse(json_data, status=status.HTTP_200_OK, content_type='application/json')
json_error = JSONRenderer().render(serializer.errors)
return HttpResponse(json_error, status=status.HTTP_400_BAD_REQUEST, content_type='application/json')
if request.method == "DELETE":
json_data = request.body
stream = io.BytesIO(json_data)
python_data = JSONParser().parse(stream)
id = python_data.get("id", None)
album = Album.objects.get(id=id)
album.delete()
json_error = JSONRenderer().render(
{"message": "album is successfully deleted"})
return HttpResponse(json_error, status=status.HTTP_204_NO_CONTENT, content_type='application/json')
#uls.py
path('list/', views.AlbumAPIView)