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

Django中select_related未返回关联表数据的原因咨询

问题原因

select_related('badge')的作用是执行SQL JOIN查询,把Requirement和关联的Badge数据一次性拉取出来,避免后续访问关联对象时触发额外数据库请求,但它不会自动让values()返回关联模型的字段。

values()默认只返回当前查询模型(这里是Requirement)的字段,要包含Badge的字段,必须显式指定,格式为关联外键名__字段名。

解决方案

修改视图中的查询代码,明确列出需要的字段:

def get_requirements(request):
    requirements = Requirement.objects.all().select_related('badge').values(
        # Requirement表字段
        'id', 'number', 'name', 'description',
        # Badge表字段,用badge__前缀
        'badge__id', 'badge__level', 'badge__name', 'badge__description'
    )
    return JsonResponse(list(requirements), safe=False)

如果想自动获取两张表的所有字段,可以动态生成字段列表:

from django.db.models.fields import Field

def get_requirements(request):
    # 获取Requirement的所有字段名
    req_fields = [field.name for field in Requirement._meta.get_fields() if isinstance(field, Field)]
    # 获取Badge的所有字段名,加上badge__前缀
    badge_fields = [f'badge__{field.name}' for field in Badge._meta.get_fields() if isinstance(field, Field)]
    
    requirements = Requirement.objects.all().select_related('badge').values(*req_fields + badge_fields)
    return JsonResponse(list(requirements), safe=False)
额外说明
  • 别删掉select_related('badge'),它能保证只执行一次数据库查询,避免多次请求的性能问题。
  • 返回的JSON里,Badge的字段会是badge__id这种格式的键,要是觉得别扭,也可以用annotate重命名字段,比如annotate(badge_name=F('badge__name')),这样返回的键就是badge_name了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:50:18