在Django中使用select_related无法获取关联模型属性的问题
问题分析与解决方案
你的实现方式不正确,导致无法返回username,核心问题出在序列化器配置和查询集字段选择这两个地方:
- 现有
TypingTestSerializer中的user字段默认只会输出外键的主键值(即user_id),没有关联UserSerializer来序列化关联的UserProfile对象 - 查询集里的
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
相关产品推荐
相关产品推荐

