如何将指定SQL查询转换为对应Comments模型的Django ORM代码
现有模型定义
class Comments(models.Model): parent = models.ForeignKey(to="self", null=True, on_delete=models.CASCADE) # 主键id为Django自动生成的自增整数字段
需求说明
你提供的SQL实现的是:筛选parent_id为1、2、3、4的评论中,每个parent分组下id最小的前2条评论。
对应ORM写法
写法1:完全匹配原SQL相关子查询逻辑
需要先导入ORM依赖:
from django.db.models import Count, OuterRef, Subquery, IntegerField
查询代码:
# 构造相关子查询:统计和当前评论同parent_id、且id小于等于当前评论id的总数量 sub_query = Comments.objects.filter( parent_id=OuterRef("parent_id"), id__lte=OuterRef("id") ).values("parent_id").annotate( cnt=Count("id") ).values("cnt") # 外层查询先关联子查询结果,再过滤符合条件的记录 comment_list = Comments.objects.annotate( sub_count=Subquery(sub_query, output_field=IntegerField()) ).filter( parent_id__in=[1,2,3,4], sub_count__lte=2 )
写法2:更高效的窗口函数实现(Django 2.0+支持,逻辑完全等价,执行性能更高)
导入依赖:
from django.db.models import Window, F from django.db.models.functions import RowNumber
查询代码:
comment_list = Comments.objects.filter( parent_id__in=[1,2,3,4] ).annotate( # 按parent_id分组,组内按id升序排列生成行号 row_num = Window( expression=RowNumber(), partition_by=F("parent_id"), order_by=F("id").asc() ) # 取每个分组的前2条 ).filter(row_num__lte=2)
内容的提问来源于stack exchange,提问作者realhuhu
相关产品推荐
相关产品推荐

