ORM 中没做外键关联,如何进行外联查询
class Bk_set(models.Model):
bk_set_name = models.CharField(verbose_name="信息系统中文全称", max_length=50)
bk_set_id = models.CharField(verbose_name="集群id", max_length=20, null=True, blank=True)
...
class Dedicated_lines(models.Model):
set_id=models.CharField(verbose_name="集群ID", max_length=50, null=True, blank=True)
...
要用Django ORM实现相似的左外连接查询,您可以使用annotate()
方法结合Subquery()
和OuterRef()
来模拟左外连接的行为。这种方法不如直接使用外键关联直观或高效,但如果您无法或不想改变模型结构,这是一种可能的解决方案。以下是如何实现的示例:
- 首先,确保已经导入了必要的Django模块:
from django.db.models import Subquery, OuterRef, CharField, Value
from your_app.models import Bk_set, Dedicated_lines
- 然后,准备子查询,这个子查询将从
Bk_set
获取bk_set_name
:
subquery = Bk_set.objects.filter(
bk_set_id=OuterRef('set_id')
).values('bk_set_name')[:1]
- 接下来,使用
annotate()
来给每个Dedicated_lines
对象添加一个新字段bk_set_name
:
dedicated_lines_with_set_name = Dedicated_lines.objects.annotate(
bk_set_name=Subquery(subquery, output_field=CharField())
)
- 最后,遍历查询结果并使用:
for line in dedicated_lines_with_set_name:
print(line.bk_inst_name, line.monthly_fee, line.set_id, line.bk_set_name)
这段代码做了以下事情:
- Subquery & OuterRef: 这两个函数被用来在
annotate()
中创建一个子查询。OuterRef
用于引用外层查询的字段。 - annotate(): 它被用来在查询结果的每一行中添加一个额外的字段,这里是
bk_set_name
。 - 执行查询: 最终的查询将在每个
Dedicated_lines
对象中添加bk_set_name
字段。
这种方法的性能可能不如直接的SQL查询,尤其是在处理大量数据时。它更复杂,但提供了一种在不直接使用SQL的情况下在Django ORM中实现相似功能的方式。如果您的应用对性能要求较高,或者这类查询非常频繁,可能还是考虑优化数据库模型,设置适当的外键关系会更有效。
from django.db.models import Sum
grouped_lines = dedicated_lines_with_set_name.values('bk_set_name', 'set_id').annotate(total_monthly_fee=Sum('monthly_fee'))
for group in grouped_lines:
bk_set_name = group['bk_set_name']
set_id = group['set_id']
total_monthly_fee = group['total_monthly_fee']
print(f"Bk_set Name: {bk_set_name}, Set ID: {set_id}, Total Monthly Fee: {total_monthly_fee}")
也可以执行sql语句
from django.db import connection
from home_application.models import Dedicated_lines, Bk_set
def execute_custom_sql_query():
with connection.cursor() as cursor:
query = """
SELECT d.bk_inst_name, d.monthly_fee, d.set_id, s.bk_set_name
FROM home_application_dedicated_lines d
LEFT JOIN home_application_bk_set s
ON d.set_id = s.bk_set_id
"""
cursor.execute(query)
result = cursor.fetchall()
return result
# 调用这个函数以执行查询并获取结果
results = execute_custom_sql_query()
# 打印结果
for row in results:
print(row)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本