Django Создание расширенного пользователя с помощью сериализатора

Я работаю над расширением базовой модели User дополнительными полями, я создал модель Profile, которая должна иметь OneToOneRelation. Я работаю с сериализаторами. Теперь, когда я пытаюсь опубликовать фиктивного пользователя, я получаю эту ошибку:

TypeError: User() получил неожиданный аргумент ключевого слова 'street'

если я отправляю только пользователя, все работает хорошо. Я знаю, что аргумент 'street' не является частью пользователя, а частью профиля, который должен храниться позже.

Я пытался решить эту проблему с помощью 'request.POST.pop' для каждого значения и парсинга в dict, но тогда данные не передаются. данные не передаются. Также я не добился успеха с Signals.

Есть ли у кого-нибудь идея, как мне заставить это работать, поскольку пользователь и профиль будут созданы одновременно, пользователь должен сохраниться первым и передать id, который он генерирует, профилю, который является ссылкой на него.

Models.py:

class Profile(models.Model):

    user = models.OneToOneField(User, on_delete=CASCADE, null=True)
    street = models.CharField(name="street", max_length=100)
    number = models.CharField(name="number", max_length=10)
    plz = models.CharField(name="plz", max_length=10)
    city = models.CharField(name="city", max_length=100)
    phone = models.CharField(name="phone", max_length=20)
    locked = models.BooleanField(name="locked", default=False)

Serializer.py:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = '__all__'

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ['street', 'number', 'plz', 'city', 'phone']

Views.py:

@api_view(['POST'])
def userCreate(request):

    userSerializer = UserSerializer(data=request.data)
    if userSerializer.is_valid():
        user = userSerializer.create(validated_data=request.data)
        profileSerializer = ProfileSerializer(instance=user ,data=request.data)
        if profileSerializer.is_valid():
            profileSerializer.create()
        return Response(status=status.HTTP_200_OK)
    return Response(status=status.HTTP_400_BAD_REQUEST)

Попробуйте это:

        profileSerializer = ProfileSerializer(data=request.data)
        if profileSerializer.is_valid():
            profileSerializer.save(user=user)

Передача instance=user приведет к тому, что ProfileSerializer будет работать с обновлением объекта пользователя (что вызывает ошибку) вместо создания нового экземпляра Profile.

Вы можете переписать сериализатор, чтобы включить в него профиль. А затем переопределить метод create.

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = '__all__'

    def create(self, validated_data):
        profile_data = validated_data.pop('profile')
        user = User.objects.create(**validated_data)
        Profile.objects.create(**profile_data, user=user)
        return user

Тогда ваш взгляд становится:

@api_view(['POST'])
def userCreate(request):

    userSerializer = UserSerializer(data=request.data)
    if userSerializer.is_valid():
        user = userSerializer.save()
        return Response(status=status.HTTP_200_OK)
    return Response(status=status.HTTP_400_BAD_REQUEST)

Запрос к серверу должен быть изменен следующим образом:

{
 profile: {
  ... // profile specific attributes like street, number, city
 },
... // user specific attibutes
}

PS: Для обновления экземпляра необходимо переопределить update метод serializer.

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