Django跨多数据库无外键场景下合并两个QuerySet的实现问题
解决方案
方案1:小数据量快速实现
直接给Overeenkomst实例绑定关联的Object属性,代码改动最小:
# view.py 修改后代码 def ovk_overview(request): ctx={} overeenkomsten = models.Overeenkomst.objects.filter(park=request.session['park_id']) ovk = [] for overeenkomst in overeenkomsten: # 取对应Object实例,用first()避免ID不存在时报错 related_obj = models.Object.objects.using('database2').filter(pk=overeenkomst.object).first() # 给当前实例绑定额外属性,避免和原有object字段重名 overeenkomst.related_object = related_obj ovk.append(overeenkomst) ctx['overeenkomsten'] = ovk return render(request, 'overeenkomsten/overzicht.html', context=ctx)
对应模板修改,把{{ ovk.object.omschrijving}}替换为:
{{ ovk.related_object.omschrijving|default:"无匹配数据" }}
方案2:大数据量性能优化(推荐)
避免循环内N+1查询,仅查询2次数据库即可完成所有数据关联:
# view.py 修改后代码 def ovk_overview(request): ctx={} overeenkomsten = models.Overeenkomst.objects.filter(park=request.session['park_id']) # 第一步:提取所有需要关联的Object ID object_ids = [item.object for item in overeenkomsten] # 第二步:批量查询所有关联Object,生成ID到实例的映射字典 obj_map = { obj.id: obj for obj in models.Object.objects.using('database2').filter(pk__in=object_ids) } # 第三步:循环绑定关联属性 ovk = [] for overeenkomst in overeenkomsten: overeenkomst.related_object = obj_map.get(overeenkomst.object) ovk.append(overeenkomst) ctx['overeenkomsten'] = ovk return render(request, 'overeenkomsten/overzicht.html', context=ctx)
模板修改逻辑和方案1一致。
额外说明
- 现有模型字段名
object是Python内置关键字,建议后续迭代改为object_id避免命名冲突 - 若不想绑定实例属性,也可以直接构造字典存入
ovk列表,自定义所有需要返回的字段即可
内容的提问来源于stack exchange,提问作者Jeebeevee
相关产品推荐
相关产品推荐

