Есть ли способ установить 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