DRF - Пользовательский сериализатор - предварительное заполнение данных по запросу.user

У меня есть модель:

class Income(...):
    user = ForeignKey(User....) # not null
    type = ...
    amount = ...

И специальный немодельный сериализатор, который должен (помимо прочего) создавать Income объекты для этого пользователя.

class WelcomeWizardSerializer(serializers.Serializer):
    applicant = serializers.HiddenField(default=serializers.CurrentUserDefault())
    applicant_incomes = IncomeSerializer(many=True, required=True)

Очевидно, что мне нужно сказать IncomeSerializer использовать applicant в качестве user. В противном случае WelcomeWizardSerializer возвращает ошибки:

{'applicant_incomes': [{'user': [ErrorDetail(string='Toto pole je povinné.', code='required')]}, {'user': [ErrorDetail(string='Toto pole je povinné.', code='required')]}]}

Как я могу это сделать?

@action(['POST'], detail=False, url_path='from-welcome-wizard')
def from_welcome_wizard(self, request, pk=None):
    serializer = WelcomeWizardSerializer(context={'request':request}, data=request.data)
    if serializer.is_valid(): # not valid
        serializer.save()

Я знаю, что мне следует получить applicant (поскольку я не хочу использовать CurrentUserDefault в IncomeSerializer) и добавить его к объектам data['incomes'], но я не знаю, где/когда будет подходящее место/время.

Как видно из сообщения об ошибке, у вас проблема с WelcomeWizardSerializer.applicant_incomes, а не с WelcomeWizardSerializer.applicant. С WelcomeWizardSerializer.applicant все в порядке.

Очевидно, что у вас есть поле user внутри applicant_incomes, и вы не хотите, чтобы клиент передавал в него еще и user. Поэтому вам нужно заменить IncomeSerializer на какой-то новый сериализатор, например, IncomeDefaultUserSerializer. Внутри него вам понадобится аналогичный HiddenField, например:

user = serializers.HiddenField(default=serializers.CurrentUserDefault())

После этого нужно использовать IncomeDefaultUserSerializer внутри WelcomeWizardSerializer, и ваш вопрос будет решен.

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