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

如何将原始SQL转换为Django QuerySet?附相关模型代码

将原始SQL转换为Django QuerySet

核心逻辑拆解

原始SQL的核心行为是:

  • 查询TblKnowledge中满足状态条件的记录
  • 左关联TblUsedKnowledge统计每个知识的使用次数
  • 按使用次数倒序排序
  • 仅返回指定字段

转换后的QuerySet实现

首先导入必要的模块:

from django.db.models import Q, Count, Exists, OuterRef
from KnowledgeManagement.models import TblKnowledge, TblUsedKnowledge

基础版本(假设Status=1是TblKnowledge的字段)

knowledges = TblKnowledge.objects.filter(
    # 匹配原始SQL的逻辑优先级:(register_status=7) OR (register_status=9 AND Status=1)
    Q(register_status=TblKnowledge.its_knowledge) | 
    Q(register_status=TblKnowledge.accepted_by_security, Status=1)
).annotate(
    # 统计每个知识的使用次数,左关联自动处理无使用记录的情况(计数为0)
    use_count=Count('tblusedknowledge')
).order_by(
    # 按使用次数倒序排序
    '-use_count'
).values(
    # 指定需要返回的字段,与原始SQL的SELECT对应
    'KnowledgeCode', 'KnowledgeTitle', 'CreateDate', 'CreatorUserID_id'
)

模型字段修正说明

注意:你提供的TblKnowledge和TblUsedKnowledge模型中没有定义Status字段,这与原始SQL中的Status=1条件冲突。如果Status是TblUsedKnowledge的字段,需要用子查询保留左关联的语义(避免过滤掉无使用记录的知识),代码调整为:

knowledges = TblKnowledge.objects.filter(
    Q(register_status=TblKnowledge.its_knowledge) | 
    Q(
        register_status=TblKnowledge.accepted_by_security,
        # 子查询判断是否存在符合条件的使用记录
        Exists(
            TblUsedKnowledge.objects.filter(
                knowledge=OuterRef('pk'),
                Status=1
            )
        )
    )
).annotate(
    use_count=Count('tblusedknowledge')
).order_by(
    '-use_count'
).values(
    'KnowledgeCode', 'KnowledgeTitle', 'CreateDate', 'CreatorUserID_id'
)

返回模型实例而非字典

如果需要返回TblKnowledge模型实例(而非字典),将values()替换为only()以减少查询字段:

knowledges = TblKnowledge.objects.filter(
    Q(register_status=TblKnowledge.its_knowledge) | 
    Q(register_status=TblKnowledge.accepted_by_security, Status=1)
).annotate(
    use_count=Count('tblusedknowledge')
).order_by(
    '-use_count'
).only(
    'KnowledgeCode', 'KnowledgeTitle', 'CreateDate', 'CreatorUserID'
)

关键对应点说明

  • 左关联:Django ORM通过annotate(Count('tblusedknowledge'))自动完成左关联,tblusedknowledge是反向关联的默认名称(因TblUsedKnowledge的外键未指定related_name)。
  • 逻辑条件:用Q对象严格复刻原始SQL的逻辑优先级,避免因运算符优先级导致的过滤错误。
  • 分组:由于KnowledgeCode是TblKnowledge的主键,Django ORM在使用annotate时会自动按主键分组,无需额外指定group_by。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:30:51