Сохранение двух обьектов в одном запроса Django Rest Framework
Решил попробовать сохранить два обьекта в одном запросе, переопределив сериализатор djoser для создания юзера(хочу авторизовываться по его юрлке):
{
"email": "[email protected]",
"password": "12345",
"user_customer": {
"name": "bbbbb",
"surname": "aaaaa",
"phone": "+71234567",
"address": "ул.Пушкина"
}
}
По сути попытался симитировать создание юзера и одновременное создание контактной информации о нем. Однако, джанго не позволяет мне сериализовать user_customer как обьект. Сам код сериализаторов выглядит следующим образом:
User = get_user_model()
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
exclude = ['id']
class RegisterUserSerializer(UserCreateSerializer):
user_customer = CustomerSerializer(many=False, read_only=False)
class Meta(UserCreateSerializer.Meta):
fields = '__all__'
def create(self, validated_data):
user_customer = validated_data.pop('user_customer')
user = User.objects.create(**validated_data)
Customer.objects.create(id=user, **user_customer)
return user
#так как метод save лишь вызывает perform_create и обрабатывает исключение, переопределим его
def perform_create(self, validated_data, *args, **kwargs):
with transaction.atomic():
user_customer = validated_data.pop('user_customer')
email = validated_data.pop('email')
password = validated_data.pop('password')
user = User.objects.create_user(email=email, password=password)
Customer.objects.create(id=user, **user_customer)
return user
При таких данных и таком состоянии кода вылетает ошибка, что QueryDict с данными user_customer не может быть инстансом Customer(что довольно логично). Не могу понять, как и что мне лучше сделать, чтобы это заработало? Впринципе есть несколько вариантов: либо самому написать метод во вьюшке, что впринципе не сложно, но очень хочется, чтобы все было красиво, лаконично и автоматически(кейс то вроде довольно дефолтный); либо переписать to_representation у CustomerSerializer, что, откровенно говоря, красивым и лаконичным не назовешь. Очень бы хотел услышать ваши идеи по данному вопросу и найти решение данного кейса на будущее.
Ответы (1 шт):
Вообщем, вся проблема в том, что в Djoser в своем сериализаторе UserCreateSerializer(от которого наследуется мой сериализатор), вызывает метод validate с данными, в которых находится мой user_customer. Недолго подумав, решил проблему переопределив метод validate таким образом:
def validate(self, attrs):
attrs_without_customer = attrs.copy()
attrs_without_customer.pop('user_customer')
super().validate(attrs_without_customer)
return attrs