Django REST API如何关联User与Blog模型获取指定格式接口输出
实现匹配输出格式的解决方案
核心调整点
默认ModelSerializer处理外键字段时,只会序列化外键对应的ID值,要输出关联用户的其他字段,只需要在Blog序列化器中通过source参数读取关联User实例的属性,再显式指定返回字段即可,不需要修改模型层代码。
具体代码修改
1. 修改 serializers.py 中的 BlogSerializers
class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'username', 'email', 'first_name', 'is_staff', ] class BlogSerializers(serializers.ModelSerializer): # 直接映射关联用户的对应字段,平铺到序列化输出中 user_name = serializers.CharField(source='user.username', read_only=True) first_name = serializers.CharField(source='user.first_name', read_only=True) email = serializers.EmailField(source='user.email', read_only=True) class Meta: model = Blog # 显式指定返回字段,完全匹配目标输出结构 fields = [ 'blog_id', 'title', 'description', 'image', 'create_at', 'update_at', 'user', 'user_name', 'first_name', 'email' ]
2. 优化 views.py 中的博客列表接口查询性能
如果直接查询所有Blog实例,读取关联用户字段时会触发N+1次数据库查询,通过select_related做联表查询即可避免:
@api_view(['GET']) def get_blogs(request): # 联表关联user表,一次性查出所有关联用户数据 blogs = Blog.objects.select_related('user').all() serializer = BlogSerializers(blogs, many=True) return Response(serializer.data) @api_view(['GET']) def get_users(request): user = User.objects.all() serializer = UserSerializer(user, many=True) return Response(serializer.data)
效果说明
修改后的接口返回结构和指定的格式完全一致:
- 保留原来的
user: 1外键ID字段 - 平铺输出用户对应的
user_name、first_name、email字段,不会出现嵌套的用户对象结构 - ImageField字段在配置好媒体文件路径后,会自动输出带媒体前缀的访问路径,和示例中的图片返回格式一致,不需要额外修改
- 所有关联用户字段设置为
read_only=True,不会影响Blog的创建、更新等写接口的原有逻辑
补充:如果后续需要返回的用户字段更多,可以继续在BlogSerializers中用
source='user.xxx'的方式追加映射,不需要额外修改查询逻辑。
内容的提问来源于stack exchange,提问作者techedifice
相关产品推荐
相关产品推荐

