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()来模拟左外连接的行为。这种方法不如直接使用外键关联直观或高效,但如果您无法或不想改变模型结构,这是一种可能的解决方案。以下是如何实现的示例:

  1. 首先,确保已经导入了必要的Django模块:
from django.db.models import Subquery, OuterRef, CharField, Value
from your_app.models import Bk_set, Dedicated_lines
  1. 然后,准备子查询,这个子查询将从Bk_set获取bk_set_name
subquery = Bk_set.objects.filter(
bk_set_id=OuterRef('set_id')
).values('bk_set_name')[:1]
  1. 接下来,使用annotate()来给每个Dedicated_lines对象添加一个新字段bk_set_name
dedicated_lines_with_set_name = Dedicated_lines.objects.annotate(
bk_set_name=Subquery(subquery, output_field=CharField())
)
  1. 最后,遍历查询结果并使用:
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)
posted @   蓝天008  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示