how to pass extra context data to serializers in django-rest-framework ?

Reading Time : ~ .

  • Serializers are used to validate the data 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
    
  • Django serializers designed in such a way that makes an application more powerful and simplified the development process.
  • To pass extra context data to the serializer we use "context" parameter.
  • "context" parameter takes the data in the form of a dictionary. 
  • we access the context data inside serializer with 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  serializers

class 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
    # .......

  • In function based views we can pass extra context to serializer with "context" parameter with a dictionary.  To access the extra context data inside the serializer we can simply access it with "self.context".
    From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.context.get("exclude_email_list", [])'. context is dictionary and "getis a dictionary method to access the data.
  • 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
            }
    
  • If we want to add extra data to the default we can simply overload it and return the context after updating the context (shown as above)

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

    By Posted On
SENIOR DEVELOPER at MICROPYRAMID

Need any Help in your Project?Let's Talk

Latest Comments
Related Articles
Improving page speed score in Google Page Score test- PART1 Chaitanya Kattineni

Google's Page Speed Insights measures the performance of a page for mobile devices and desktop devices. It fetches the url twice, once with a mobile ...

Continue Reading...
E-commerce (paypal) integration with Django Ashwin Kumar

E-commerce is integration is becoming almost essential for every web application now a days. There are so many payment gateways to integrate with our application. ...

Continue Reading...
Extract text with OCR for all image types in python using pytesseract Shirisha Gaddi

Optical Character Recognition(OCR) is the process of electronically extracting text from images or any documents like PDF and reusing it in a variety of ways ...

Continue Reading...

Subscribe To our news letter

Subscribe to our news letter to receive latest blog posts into your inbox. Please fill your email address in the below form.
*We don't provide your email contact details to any third parties