Skip to main content
 首页 » 编程设计

python之如何使用 Django 的 ORM 进行过滤聚合

2025年02月15日22lonelyxmas

我有一个像这样的 Django 模型:

class Post(models.Model): 
 
    name = models.CharField(max_length=10) 
 
class Topic(models.Model): 
 
    name = models.CharField(max_length=10) 
 
class Annotator(models.Model): 
 
    post = models.ForeignKey(Post, related_name='annotations') 
 
    topic = models.ForeignKey(Topic) 
 
    name = models.CharField(max_length=10) 

如何找到所有没有与特定 topic 和 Annotator name 值关联的 Annotator 记录的 Post 记录?

如果没有 topic 和 name 过滤条件,Django 查询将如下所示:

qs = Post.objects.all() 
qs = qs.annotate(annotations_count=Count('annotations')) 
qs = qs.filter(annotations_count=0) 

但我想做的是:

qs = Post.objects.all() 
qs = qs.annotate(annotations_count=Count('annotations' where name='annotator1' and topic='topic1')) 
qs = qs.filter(annotations_count=0) 

这显然是不合法的。

我目前正在使用 .raw() 执行传统的 LEFT OUTER JOIN,因此我可以在 WHERE 子句中执行此过滤,但这会阻止我重新使用我使用 Django ORM 重写的大量代码和过滤器。

如何在 Django 的 .annotate() 方法中添加过滤条件,或者以其他方式达到相同的结果?

我正在使用 Django 1.11。

请您参考如下方法:

How do I find all Post records that don't have an associated Annotator record with a specific topic and Annotator name value?

如果我理解你的问题,你正在寻找 .exclude() :

Post.objects.exclude( 
    annotator__topic='topic1',  
    annotator__name='annotator1' 
)