Django中如何查询跨三个模型的关联关系获取Station名称?
问题解决方案
问题根源
你调用values()方法时,默认仅返回当前Exercise模型的自有字段,外键station在返回结果中仅存储关联Station表的主键ID,不会自动带出关联的name属性。同时你之前的筛选逻辑Station.objects.filter(name=exercises[0])存在错误,exercises[0]是包含Exercise全字段的字典,不是站点名称或ID,无法匹配到结果。
方案1:直接使用ORM实例(最推荐)
去掉values()调用,直接获取Exercise实例,配合select_related提前联表查询关联的Station数据,避免后续遍历产生N+1性能问题:
def planodet(request, id): plan = Workout.objects.get(id=id) # 直接获取实例集合,select_related提前加载关联的station数据 exercises = plan.exercises.all().select_related('station')
遍历实例时可直接跨外键访问站点名称:
# 视图中取值示例 for exercise in exercises: station_name = exercise.station.name print(station_name) # 模板中取值示例 {% for exercise in exercises %} 练习:{{ exercise.exercise }},所属站点:{{ exercise.station.name }} {% endfor %}
方案2:保留values()调用,显式指定关联字段
如果确实需要返回字典格式的数据,可以在values()中显式声明要获取的关联字段,使用双下划线__跨表引用:
def planodet(request, id): plan = Workout.objects.get(id=id) # 显式指定要返回的字段,station__name即为关联的站点名称 exercises = plan.exercises.values('exercise', 'series', 'reps', 'station__name')
取值时直接读取字典对应的key即可:
station_name = exercises[0]['station__name']
方案3:单独查询Station(不推荐)
如果要沿用你原来的筛选思路,需要先从Exercise返回结果中取出station的主键ID,再用ID查询Station对象:
# 从values返回的字典中取station的ID station_id = exercises[0]['station'] # 用ID查询对应的Station对象 station = Station.objects.get(id=station_id) station_name = station.name
该方法会额外产生数据库查询请求,遍历多组Exercise时会出现N+1性能问题,仅适合单条数据查询场景。
内容的提问来源于stack exchange,提问作者overclock
相关产品推荐
相关产品推荐

