How to update User Profile and User in one request in Django Rest Framework?

How to update User Profile and User in one request in Django Rest Framework?

Update User Profile and User in one request.

Gaurav Sharma's photo
Gaurav Sharma
·May 29, 2022·

2 min read

Subscribe to our newsletter and never miss any upcoming articles

Play this article

Let’s say you have a Django User model and a UserProfile model connected via OneToOneField . Your goal is to serialize both the models together in a single request to perform needed CRUD operations.

Note: I am not assuming whether you have a custom User model or provided by Django, this blog’s code will work with both custom and Django’s User model.

Let’s say your UserProfile model looks something like this:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='userprofile', on_delete=models.CASCADE)
    # custom fields for userprofile
    mobile = models.CharField(max_length=50)
    #...

Let’s create a serializer for our UserProfile & User model in our [serializers.py](http://serializers.py) file (inside our Django app):

from django.contrib.auth import get_user_model
from rest_framework import serializers
from accounts.models import UserProfile

User = get_user_model()

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('mobile',)

class UserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(source="userprofile", many=False)

    class Meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name', 'profile')

        # Custom .update() method for serializer to handle UserProfile data update
        def update(self, instance, validated_data):
            userprofile_serializer = self.fields['profile']
            userprofile_instance = instance.userprofile
            userprofile_data = validated_data.pop('userprofile', {})

            # to access the UserProfile fields in here
            # mobile = userprofile_data.get('mobile')

            # update the userprofile fields
            userprofile_serializer.update(userprofile_instance, userprofile_data)

            instance = super().update(instance, validated_data)
            return instance

This is it, now we can create our APIView to perform CRUD operations:

from django.contrib.auth import get_user_model
from rest_framework.generics import RetrieveUpdateAPIView
from rest_framework.permissions import IsAuthenticated
from accounts.serializers import UserSerializer

User = get_user_model()

class UserAPIView(RetrieveUpdateAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.all()
    permission_classes = (IsAuthenticated,)

    def get_object(self):
        return self.request.user

Any doubts? Write it down in the comments.

For more such crispy blogs daily, follow Dev.Junction, subscribe to our newsletter and get notified.

Did you find this article valuable?

Support Dev.Junction by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
 
Share this