Как получить доступ к полю User Model в сериализаторе расширенной User Model в Django Rest Framework?

Я создаю простое приложение для регистрации/входа в Django Rest Framework, используя Rest API с аутентификацией Django Rest Knox, в котором при регистрации пользователь также загружает CSV файл (это необязательное поле).

У меня есть Person Модель, которая является расширенной (производной или OneToOne) Моделью User Модели и имеет FileField для загружаемого файла.

У меня есть два ModelSerializer, один основан на User Модели с именем MainRegisterSerializer и сериализует поля username, email и password, а другой основан на Person Модели с именем RegisterSerializer, которая сериализует поле FileField и register (которое инициализируется конструктором класса MainRegisterSerializer.

Теперь, в views.py, я обращаюсь к RegisterSerializer, чтобы получить данные из фронта, который включает username, email и password поля из User Model, и FileField из Person Model.

Но, когда я ввожу данные во front-end и загружаю файл, и нажимаю на кнопку POST, я получаю следующую ошибку:

KeyError at /api/v1/register
'username'

на строке кода user = User.objects.create_user(validated_data['username'], validated_data['email'], validated_data['password'], validated_data['file']) в serializers.py файле.

Мой views.py - это:

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]
        })

Мой serializers.py - это:

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

Мой models.py - это:

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")

Я уже пробовал различные решения, описанные здесь на stackoverflow, но ни одно из них не помогло мне, поэтому я и размещаю этот вопрос. Любая помощь будет оценена по достоинству. Спасибо.

Если вы посмотрите на подтвержденные данные, то увидите, что данные, принадлежащие сериализатору MainRegisterSerializer, будут доступны с ключом register. А данные, принадлежащие сериализатору RegisterSerializer будут доступны с ключом file.

проверенные данные :

{'register': OrderedDict([('username', 'test'), ('email', 'test@gmail.com'), ('password', 'test123')]), 'file': <InMemoryUploadedFile: filename.txt (text/csv)>}

Итак, чтобы получить доступ к любым полям регистра, вам нужно использовать:

validated_data['register']['username'], validated_data['register']['email'] ..etc.

для доступа к файлу вы можете использовать: validated_data['file']

Вернуться на верх