如何在Django Rest Framework中扁平化序列化含附加数据的多对多字段
解决DRF序列化关注列表时的嵌套扁平化问题
方法一:直接映射字段(适合用户字段较少的场景)
修改FollowerSerializer,不再嵌套UserSnippetSerializer,而是通过source参数直接将关注者的属性映射为顶层字段,同时保留follow_date:
class UserSnippetSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['username'] # 可根据需求添加其他用户字段 class FollowerSerializer(serializers.ModelSerializer): # 直接从follower对象中取字段,作为当前序列化器的顶层字段 username = serializers.CharField(source='follower.username') # 如需其他用户字段,比如id、email,按同样方式添加 # user_id = serializers.IntegerField(source='follower.id') # email = serializers.EmailField(source='follower.email') class Meta: model = Follower fields = ['username', 'follow_date'] # 包含用户字段和关注时间 class FullUserSerializer(serializers.ModelSerializer): followers = FollowerSerializer(source='user.followers', many=True) following = FollowerSerializer(source='user.following', many=True) class Meta: model = Profile fields = ['username', 'followers', 'following']
方法二:重写to_representation方法(适合用户字段较多的场景)
如果需要序列化的用户字段较多,逐个映射太繁琐,可重写FollowerSerializer的to_representation方法,合并用户数据和关注时间:
class UserSnippetSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['username', 'email', 'id'] # 按需添加字段 class FollowerSerializer(serializers.ModelSerializer): class Meta: model = Follower fields = ['follow_date'] def to_representation(self, instance): # 先获取关注时间的序列化数据 follow_data = super().to_representation(instance) # 序列化关注者的用户信息 user_data = UserSnippetSerializer(instance.follower).data # 合并两个字典,实现扁平化结构 return {**user_data, **follow_data} class FullUserSerializer(serializers.ModelSerializer): followers = FollowerSerializer(source='user.followers', many=True) following = FollowerSerializer(source='user.following', many=True) class Meta: model = Profile fields = ['username', 'followers', 'following']
说明
两种方法核心思路一致:将关联的用户字段直接提升到当前序列化层级,避免嵌套。方法一直观简洁,适合字段少的场景;方法二更灵活,适配大量用户字段的序列化需求。
内容的提问来源于stack exchange,提问作者mvanb
相关产品推荐
相关产品推荐

