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

在Django中使用select_related无法获取关联模型属性的问题

问题分析与解决方案

你的实现方式不正确,导致无法返回username,核心问题出在序列化器配置和查询集字段选择这两个地方:

  1. 现有TypingTestSerializer中的user字段默认只会输出外键的主键值(即user_id),没有关联UserSerializer来序列化关联的UserProfile对象
  2. 查询集里的only("userName")写法错误,跨表字段需要用__连接,应该写成user__userName

正确实现步骤

1. 修改序列化器,嵌套关联的用户序列化器

在TypingTestSerializer中,把user字段指定为UserSerializer类型,这样序列化时会自动把关联的用户信息展开:

class TypingTestSerializer(serializers.ModelSerializer):
    # 嵌套UserSerializer,序列化关联的UserProfile对象
    user = UserSerializer()
    
    class Meta: 
        model = TypingTest
        fields = ('id','user','time','wpm','accuracy','raw','dateTaken')

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('userName','email','profilePhoto','rank')

2. 优化查询集,正确使用select_related和字段选择

select_related('user')已经能实现连表查询,但如果想进一步限制返回的字段(减少数据传输),需要用__指定跨表字段:

@protected_resource()
@api_view(['GET'])
def getAllTests (request):
    # 一次性查询TypingTest和关联的UserProfile,同时只加载需要的字段
    test_queryset = models.TypingTest.objects.select_related('user').only(
        'id', 'time', 'wpm', 'accuracy', 'raw', 'dateTaken',
        'user__userName', 'user__email', 'user__profilePhoto', 'user__rank'
    )
    serializer = serializers.TypingTestSerializer(test_queryset, many=True)    
    return Response(serializer.data)

3. 最终效果

修改后,返回的响应数据会包含完整的用户信息,示例格式如下:

[
    {
        "id": 1,
        "user": {
            "userName": "test_user1",
            "email": "test1@example.com",
            "profilePhoto": "/default.png",
            "rank": "Novice"
        },
        "time": 60,
        "wpm": 60,
        "accuracy": 91,
        "raw": 79,
        "dateTaken": "2023-02-14T21:07:32.721899Z"
    }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:25:21