Pass Request Context to Serializer from ViewSet in Django Rest Framework

Last Updated : 22 Nov, 2025

Django REST Framework (DRF) allows passing context from a ViewSet to a Serializer. This context is a dictionary that carries extra information the serializer may need.

  • Helps validate or serialize fields based on user permissions.
  • Can include request-specific data such as IP address or headers.
  • Allows customizing serializer behavior without tying it directly to the view.
  • Supports cleaner and more flexible handling of dynamic data.

Passing the active request into serializer context in a ViewSet

Consider a project called 'myproject' with an app named 'blog':

Update settings.py

Add the app and rest framework to our "INSTALLED_APPS" in settings.py

Python
INSTALLED_APPS = [
    # ...
    'rest_framework',
    'blog',
  	# Add this for token authentication
    'rest_framework.authtoken',
]

Set Up Token Authentication

To enable token authentication, we need to configure DRF. Add the following settings in settings.py:

Python
# ...

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
}
oppll
Snapshot of project directory

Create the Post Model

In blog/models.py, define a simple Post model:

Python
from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

Run the migrations to create the database table:

python manage.py makemigrations
python manage.py migrate

Create a Serializer

In blog/serializers.py, create a serializer for the Post model. To utilize the request object inside the serializer, simply access it via self.context. We to pass any additional context we may need, including the request object, user, or custom parameters.

Python
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'content']

    def save(self, *args, **kwargs):
        request = self.context.get('request')
        if request and request.user:
          	self.author = request.user
        return super().save(*args, **Kwargs)

1. Using the context Parameter in the ViewSet

This PostViewSet handles CRUD operations for the Post model, using PostSerializer and restricting access to authenticated users with IsAuthenticated. The get_serializer method is overridden to explicitly pass the request context (self.request) to the serializer via the context argument.

Python
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
from rest_framework.permissions import IsAuthenticated

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated]

    def get_serializer(self, *args, **kwargs):
        # Pass the request context explicitly when instantiating the serializer
        kwargs['context'] = {'request': self.request}
        return super().get_serializer(*args, **kwargs)

2. Overriding get_serializer_context() in the ViewSet

This PostViewSet provides CRUD operations for the Post model, restricted to authenticated users with IsAuthenticated permission. It uses the PostSerializer and passes the request context to the serializer by overriding get_serializer_context(). This allows the serializer to access the request data.

Python
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
from rest_framework.permissions import IsAuthenticated

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated]

    def get_serializer_context(self):
        context = super().get_serializer_context()
        # Add request context
        context['request'] = self.request
        return context

Set Up URLs

In blog/urls.py, set up the URLs for the ViewSet:

Python
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from blog.views import PostViewSet

router = DefaultRouter()
router.register(r'posts', PostViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
]

Create Token Authentication for Users

To use token authentication, we'll need to create tokens for users. We can do this using the Django shell. First, create a superuser:

python manage.py createsuperuser

create

Then, enter the shell:

python manage.py shell

Inside the shell, create a token for the superuser:

Python
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token

user = User.objects.get(username='your_username')
token = Token.objects.create(user=user)
print(token.key)
createtoekn

Run the Server

python manage.py runserver

Create a Post

Use a GET request to "http://127.0.0.1:8000/posts/"

1
Output

In the headers, add Authorization: Token your_token_key.

oppp

In the body, include a JSON object with title and content.

{
"title": "First Post",
"content": "This is the content of the first post."
}

token
Output

Fetch All Posts

  • Use a GET request to http://127.0.0.1:8000/posts/.
  • Include the same authorization header.
get
Output
Comment