You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST接口返回UserProject数据时如何嵌入关联Project模型字段

实现方案

1. 修改序列化器(核心改动)

你需要在UserprojectSerializer中嵌套关联Project的序列化数据,有两种常用实现方式:

方式1:返回完整的Project对象

直接把你已经定义好的ProjectSerializer嵌套进去,会返回Project表的所有字段:

class UserprojectSerializer(serializers.ModelSerializer):
    # 嵌套Project序列化器,read_only表示只做返回用,不需要传参
    project = ProjectSerializer(read_only=True)
    class Meta:
        model = Userproject
        fields = '__all__'

返回结构示例:

{
    "id": 17,
    "created_at": "2021-10-20T16:27:59.938422Z",
    "updated_at": "2021-10-20T16:27:59.945439Z",
    "user": 3,
    "project": {
        "id":51,
        "name": "项目名",
        "descriptor": "项目描述",
        "created_at": "xxx",
        "updated_at": "xxx"
    }
}

方式2:自定义字段名,只取Project指定字段

如果你想按你示例里的projectname、projectDescriptor命名单独返回字段,不用嵌套结构,可以这么写:

class UserprojectSerializer(serializers.ModelSerializer):
    projectname = serializers.CharField(source='project.name', read_only=True)
    projectDescriptor = serializers.CharField(source='project.descriptor', read_only=True)
    class Meta:
        model = Userproject
        # 记得把新增的字段加到fields里,不用__all__的话就手动列所有要返回的字段
        fields = ['id', 'created_at', 'updated_at', 'user', 'project', 'projectname', 'projectDescriptor']

2. 优化现有代码冗余问题

视图层优化

你现在的代码对User表做了两次查询(一次exists、一次get),可以合并成一次查询,同时用select_related提前关联Project表,避免N+1查询性能问题:

class GetUserDataByNameView(APIView):
    def get(self, request, username):
        try:
            # 一次查询拿到用户对象
            user = User.objects.get(username=username)
            # select_related提前查关联的project,减少数据库查询次数
            queryset = Userproject.objects.filter(user_id=user.id).select_related('project')
            readSerializer = UserprojectSerializer(queryset, many=True)
            return Response(readSerializer.data)
        except User.DoesNotExist:
            # 建议这里状态码改成404,更符合REST接口规范,不需要可以保留200
            return Response({"status": "error", "data":"no user with this username"}, status=404)

模型层优化

你当前Userproject的__str__方法返回的是数字id,会触发类型错误,需要改成字符串:

def __str__(self):
    return str(self.id)

其他建议

  • 如果不需要自定义返回字段,优先用方式1的嵌套序列化,扩展性更好
  • 序列化器里的ProjectSerializer已经通过ModelSerializer关联了模型字段,不需要手动重复定义name、descriptor字段,除非你要修改默认的校验规则,可以删掉冗余的字段定义。

内容的提问来源于stack exchange,提问作者Nic0lodeon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:45:05