Open In App

Get Request.User in Django-Rest-Framework Serializer

Last Updated : 07 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In Django Rest Framework (DRF), serializers are used to transform complex data types, such as queryset and model instances, into native Python data types. One common requirement is to access the request.user within a serializer, which is particularly useful when you need to customize the serialization based on the authenticated user. This article will guide you through the process of accessing the request.user in a DRF serializer, describing multiple methods with example code and explanations.

Get Request.User in Django-Rest-Framework Serializer

Step 1: Setting Up the Django Project

First, let's create a new Django project and set up DRF:

python -m venv environment
environment\Scripts\activate
pip install django djangorestframework

django-admin startproject myproject
cd myproject
python manage.py startapp main
file-structure-
Django Project Structure

Here, we will be using the default token based authentication. So, add the rest_framework, rest_framework.authtoken and the newly created app, main, to your INSTALLED_APPS in myproject/settings.py:

INSTALLED_APPS = [
...,
'rest_framework',
'rest_framework.authtoken',
'main',
]

Configuring Token Authentication

To use the Token Authentication, we need to add the 'TokenAuthentication' to the Rest Framework's DEFAULT_AUTHENTICATION_CLASSES in the settings.py file. Add the following code to your myproject/settings.py to configure DRF to use token authentication:

Python
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}

Also, we have set the default permission to 'IsAuthenticated', allowing only authenticated users to access any endpoints of our project.

Step 2: Setting Up the Models

Let's create a simple model to work with:

Python
# main/models.py
from django.db import models
from django.contrib.auth.models import User

class Item(models.Model):
    name = models.CharField(max_length=100)
    owner = models.ForeignKey(User, related_name='items', on_delete=models.CASCADE)

    def __str__(self):
        return self.name

Run the migrations:

python manage.py makemigrations
python manage.py migrate

Step 3: Creating the Serializer

Create a serializer for the Item model:

Python
# main/serializers.py
from rest_framework import serializers
from .models import Item

class ItemSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')

    class Meta:
        model = Item
        fields = ['id', 'name', 'owner']

Step 4: Passing request Object to the Serializer

There are a few ways to pass the request object to the serializers. Below are the different ways discussed:

Method 1: Overriding the View's get_serializer_context() Method

One common way to pass the request object to the serializer is by overriding the get_serializer_context() method in your view:

Python
# main/views.py
from rest_framework import generics
from .models import Item
from .serializers import ItemSerializer
from rest_framework.permissions import IsAuthenticated


class ItemListCreateView(generics.ListCreateAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = [IsAuthenticated]

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

By doing this, the request object will be available in the serializer's context dictionary.

Method 2: Directly Passing the Context in the View

You can also directly pass the context when initializing the serializer:

Python
# main/views.py
from rest_framework import generics
from .models import Item
from .serializers import ItemSerializer
from rest_framework.permissions import IsAuthenticated

class ItemListCreateView(generics.ListCreateAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = [IsAuthenticated]

    def post(self, request, *args, **kwargs):
      	# Pass the request object while intializing the serializer
        serializer = self.get_serializer(data=request.data, context={'request': request})
        
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response(serializer.data)

Step 5: Accessing the request Object in the Serializer

In your serializer, you can access the request object from the context:

Python
# main/serializers.py
from rest_framework import serializers
from .models import Item

class ItemSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')

    class Meta:
        model = Item
        fields = ['id', 'name', 'owner']

    def create(self, validated_data):
        request = self.context.get('request')
        item = Item.objects.create(owner=request.user, **validated_data)
        return item

While using the request object, also add a check when the request is None to avoid any error.

Step 6: Setting Up the URLs

Add the view to your URLs:

Python
# main/urls.py
from django.urls import path
from .views import ItemListCreateView

urlpatterns = [
    path('items/', ItemListCreateView.as_view(), name='item-list-create'),
]

Include the app URLs in the project's URLs:

Python
# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

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

Step 7: Creating Tokens for Users

Here, we do not have any login endpoints. So we need to create tokens for users so that they can authenticate. First, ensure you have a superuser:

python manage.py createsuperuser
item

The authtoken app provides a management command named drf_create_token. It takes the username and creates a token for that user if exists. Now, create tokens for your user:

python manage.py drf_create_token <username>
generate-toekn

Run the server using the runserver command:

python manage.py runserver 

Output:

When an authenticated user access the endpoints (api/items/), he gets a success response means the list of items:

authenticated

When an unauthenticated user access the enpoint (api/items/), he gets 401 Unauthorized or 403 Forbidden response.

tokennnn

Conclusion

Accessing the request.user in a Django Rest Framework serializer can be achieved by passing the request object through the view's context. This article demonstrated how to set up a Django project, create models and serializers, and pass the request object to the serializer using various methods. Additionally, we configured token authentication to ensure that only authenticated users can access certain views. By following these steps, you can customize your serialization logic based on the authenticated user, enhancing the functionality of your DRF application.


Next Article
Article Tags :
Practice Tags :

Similar Reads