Как получить доступ к полю 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']