How do I access User Model field in the Serializer of extended User Model in Django Rest Framework?

I am creating a simple registration/login app in Django Rest Framework using Rest APIs with Django Rest Knox’s authentication, in which, upon registration, user will also upload a CSV File (which is an optional field).

I have a Person Model which is an extended (derived or OneToOne) Model of User Model and has FileField for the file to be uploaded.

I have two ModelSerializers, one is based on User Model named MainRegisterSerializer and serializes username, email and password fields, and the other is based on Person Model named RegisterSerializer, which serializes FileField and register field (that is initialized with MainRegisterSerializer class’s constructor.

Now, in views.py, I am accessing the RegisterSerializer, to get the data from front that which includes username, email and password fields from User Model, and FileField from Person Model.

But, when I enter data in front-end and upload the file, and click on POST button, I get the following error:

KeyError at /api/v1/register
'username'

on the code line user = User.objects.create_user(validated_data['username'], validated_data['email'], validated_data['password'], validated_data['file']) in serializers.py file.

My views.py is:

from rest_framework.response import Response
from knox.models import AuthToken
from .serializers import RegisterSerializer


class RegisterAPI(generics.GenericAPIView):
    serializer_class = RegisterSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        token = AuthToken.objects.create(user)
        return Response({
            "users": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": token[1]
        })

My serializers.py is:

from .models import Person
from django.contrib.auth.models import User
from rest_framework import serializers


class MainRegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'email', 'password')


class RegisterSerializer(serializers.ModelSerializer):
    register = MainRegisterSerializer()

    class Meta:
        model = Person
        fields = ['register', 'file',]
        optional_fields = ['file',]
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User.objects.create_user(validated_data['username'], validated_data['email'], validated_data['password'], validated_data['file'])
        return user

My models.py is:

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


class Person(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    file = models.FileField(verbose_name="CSV File")

I have already worked around by trying various solutions, but none of them worked for me, that’s why I am posting the question. Any help will surely be appreciated. Thanks.

While there are a number of people here sufficiently knowledgeable about DRF to possibly help you, this isn’t actually isn’t one of the identified support channels for it. You may get a better, faster answer by checking elsewhere.

See Home - Django REST framework for their recommended options.

(Now, if someone chimes in with an answer, great! It’s just that you may have better luck elsewhere if you haven’t tried those options already.)

1 Like

@KenWhitesell thanks for the suggestion. But, I would have appreciated if you had tried to help alongwith your suggestion or atleast tagged someone who know about the topic.

Unfortunately, I don’t have any suggestions, nor anyone that I know here to tag. That’s specifically why I suggested you check with the “official” (or “recognized”) support channels. This just isn’t the best place to try and find help with the issue you’ve described.

OK, thank you though for suggesting me to take help on official channels, @KenWhitesell

Hello)

user = MainRegisterSerializer()

def create(self, validated_data):
data = validated_data.pop(‘user’)
user = User.objects.create_user(**data)
validated_data.update({‘user’: user})
return super().create(validated_data)