Есть ли способ установить id существующего экземпляра в качестве значения вложенного сериализатора в DRF?

Я разрабатываю приложение для чата. У меня есть сериализатор следующего вида:

class PersonalChatRoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = PersonalChatRoom
        fields = '__all__'
    
    user_1 = UserSerializer(read_only=True)
    user_2 = UserSerializer()

поле user_1 заполняется автоматически, но клиент должен предоставить поле user_2 для создания личного чата с другим пользователем.

Моя проблема заключается в том, что при создании нового чата сериализатор пытается создать новый объект пользователя из входных данных, тем самым выдавая мне ошибки валидации. На самом деле я хочу, чтобы он принимал пользователя id и устанавливал значение поля user_2 в существующий экземпляр пользователя, который в настоящее время доступен в базе данных , а если пользователь не найден, просто возвращал ошибку валидации. (точное поведение PrimaryKeyRelatedField при создании нового объекта)

Я хочу, чтобы мои входные данные выглядели следующим образом:

{
    'user_2': 1 // id of the user
}

И когда я получаю свой объект PersonalChatRoom, я хочу получить сериализованную форму объекта user для своего поля user_2:

{
    ...,
    'user_2': {
         'username': ...,
         'the_rest_of_the_fields': ...
    }
}

Как я могу этого достичь?

views.py

class GroupChatRoomViewSet(viewsets.ModelViewSet):
    permission_classes = [IsUserVerified, IsGroupOrIsAdminOrReadOnly]
    serializer_class = GroupChatRoomSerializer

    def get_queryset(self):
        return self.request.user.group_chat_rooms.all()

    def perform_create(self, serializer):
        return serializer.save(owner=self.request.user)

Я наконец-то понял, как это сделать. Мне просто нужно было переопределить метод to_representation и сериализовать объект там. Вот код, который у меня получился:

class PersonalChatRoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = PersonalChatRoom
        fields = '__all__'
        read_only_fields = ['user_1']

    def to_representation(self, chat_room):
        """ Serialize user instances when outputing the results """
        obj = super().to_representation(chat_room)
        for field in obj.keys():
            if field.startswith('user_'):
                obj[field] = UserSerializer(User.objects.get(pk=obj[field])).data
        return obj
Вернуться на верх