【问题标题】:Is there a way to set the id of an existing instance as the value of a nested serializer in DRF?有没有办法将现有实例的 id 设置为 DRF 中嵌套序列化程序的值?
【发布时间】:2021-10-22 15:51:36
【问题描述】:

我正在开发一个聊天应用程序。我有一个这样的序列化程序:

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_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)

【问题讨论】:

    标签: json python-3.x django django-rest-framework django-serializer


    【解决方案1】:

    我终于想通了。我只需要重写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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-20
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2014-02-01
      • 2022-07-11
      • 1970-01-01
      相关资源
      最近更新 更多