How to Pass Extra Context Data to Serializers in Django-Rest-Framework

  • Generally, serializers provide basic validations based on the type of field. Model serializers use model validations(primary key, foreign key, unique, etc).
  • We not only use these basic validations but also custom validations to some of the fields.
  • For writing custom validations we may require some extra data in validation methods of serializers.
  • Django Rest Framework Serializer takes the following parameters while creating the serializer object.
read_only, write_only, required, default, initial, source,
label, help_text, style, error_messages, allow_empty,
instance, data, partial, context, allow_null
  • To pass extra context data to the serializer we use the “context” parameter.
  • The “context” parameter takes the data in the form of a dictionary.
  • we access the context data inside the serializer with the statement “self.context”

Let’s take an example to understand it more clearly.
Case: Send an email to any user with given content but, do not send email to the specific list of emails.
For this case, we need to validate the email and raise an error if it is in excluded emails list. To do this we need to have excluded emails list in serializers. We can achieve this by using “context” argument of the serializer.

serializers.py

from rest_framework import  serializersclass SendEmailSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
def validate_email(self, email):
# .....
exclude_email_list = self.context.get("exclude_email_list", [])
if email in exclude_email_list:
raise serializers.ValidationError("We cannot send an email to this user")
# .....
return email

Rest framework supports both function-based views(FBV) and generic views(class-based views CBV).

views.py

# Passing the extra context data to serializers in FBV style.
from rest_framework.decorators import api_view
from your_app.serializers import SendEmailSerializer
@api_view(['POST'])
def send_email_view(request):
# .....
context = {"exclude_email_list": ['test@test.com', 'test1@test.com']}
serializer = SendEmailSerializer(data=request.data, context=context)
# ....
# Passing the extra context data to serializers in generic CBV or ViewSets style
#ViewSets
from rest_framework import viewsets
class SendEmailViewSet(viewsets.GenericViewSet):
# ......
def get_serializer_context(self):
context = super(CommentViewSet, self).get_serializer_context()
context.update({
"exclude_email_list": ['test@test.com', 'test1@test.com']
# extra data
})
return context
# .......
#Generic Views
from rest_framework import generics
class SendEmailView(generics.GenericAPIView):
# ......
def get_serializer_context(self):
context = super(CommentViewSet, self).get_serializer_context()
context.update({
"exclude_email_list": ['test@test.com', 'test1@test.com']
# extra data
})
return context
# .......
  • It is the best way to override/overload the method get_serializer_context to pass the extra context data to the serializer.
  • In viewsets, generic views “get_serializer_context” returns the below data by default.

{

‘request’: self.request,

‘format’: self.format_kwarg,

‘view’: self

}

References:
https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py
https://github.com/encode/django-rest-framework/blob/master/rest_framework/generics.py#L131

--

--

--

Python, Django, Android and IOS, reactjs, react-native, AWS, Salesforce consulting & development company

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Generating CSV, Excel files Using Python

Functional Programming in Go

21Shares are hiring a Backend Engineer in New York

Deploying a VPC in Terraform with State Stored in S3 & Running CI/CD Pipeline with Jenkins

Installing Hadoop cluster on centos7 virtual machines

How do I buy JAVA?

Configuring AWS with Openshift to test WSO2IS

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
MicroPyramid

MicroPyramid

Python, Django, Android and IOS, reactjs, react-native, AWS, Salesforce consulting & development company

More from Medium

How split Django settings.py file

Querying with Django Q Objects

Would you manually populate Django tables?

Implementing Simple JWT Authentication in Django Rest Framework