Django Serializer如何将image_url与image_uuid等关联属性配对合并返回
实现方案
你可以通过嵌套序列化器的方式直接关联关联表的多个字段,无需分开单独拉取字段后再拼接,性能和可读性都更好,修改步骤如下:
步骤1:修改 serializer.py
首先新增两个轻量的嵌套序列化器,分别对应图片、视频的返回字段结构,再替换原来的独立字段声明:
# 新增图片嵌套序列化器 class PhotoSerializer(serializers.ModelSerializer): class Meta: model = Photo fields = ('image_url', 'uuid') # 新增视频嵌套序列化器 class VideoSerializer(serializers.ModelSerializer): class Meta: model = Video fields = ('video_url', 'uuid') class FullPostDataSerializer(serializers.ModelSerializer): # 替换原来的image_url、image_uuid字段 image = PhotoSerializer(source='photo_set', many=True, read_only=True) # 替换原来的video_url、video_uuid字段 video = VideoSerializer(source='video_set', many=True, read_only=True) goal_uuid = serializers.SlugField() creator_username = serializers.SlugField() reply_count = serializers.IntegerField() cheer_count = serializers.IntegerField() goal_description = serializers.SlugField() class Meta: model = Post fields = ( 'body', 'join_goal', 'created', 'creator_username', 'goal_description', 'reply_count', 'cheer_count', 'image', 'uuid', 'type', 'creator', 'video', 'goal_uuid' )
步骤2:优化 helper.py 的预加载配置
为了避免N+1查询,补充视频关联表的预加载:
def full_post_data_serializer(post_query_set: QuerySet): """ 返回信息流所需的帖子全量信息,包含:发布者用户名、目标描述、评论数、点赞数、图文和视频内容 参数: post_query_set: 帖子模型查询集 返回: 序列化后的信息流格式帖子数据 """ query_set_annotated = post_query_set.annotate( creator_username=F('creator__username'), goal_description=F('join_goal__goal__description'), goal_uuid=F('join_goal__goal__uuid'), reply_count=Count('replypost', distinct=True), cheer_count=Count('cheerpost', distinct=True) ).prefetch_related( Prefetch('photo_set', Photo.objects.order_by('-created')), # 新增视频集预加载,和图片保持相同的排序规则 Prefetch('video_set', Video.objects.order_by('-created')) ) return FullPostDataSerializer(query_set_annotated, many=True)
最终效果
修改完成后你就可以直接通过 response.data['image'] 获取到 [{"image_url": "xxx", "uuid": "xxx"}] 格式的列表,视频同理可以通过 response.data['video'] 获取配对的视频数据。
如果不想单独定义嵌套序列化器,也可以用 SerializerMethodField 手动拼接数据,但是性能低于嵌套序列化器方案,不推荐使用。
内容的提问来源于stack exchange,提问作者user12314098
相关产品推荐
相关产品推荐

