计算两个 Django 查询的交集:一个聚合,另一个 - 简单

Calculate intersection of two Django queries: one aggregate, another - simple

我有一个模型 VariantTag,它存储另一个名为 SavedVariant 的模型的 ids。前者有另一个 variant_tag_type_id 指向它的相对模型类型 VariantTagType。现在我正在尝试获取所有具有 only one variant_tag_type.name = 'Review' 标签的 SavedVariant ids 。为了让事情更清楚,这是我在 Django 中尝试做的事情:

    # Variants with just only one tag present                                                                          
    single_variant_ids = VariantTag.objects.values_list('saved_variant_id', flat=True) \                               
            .annotate(id_count=Count('saved_variant_id')).filter(id_count=1)                                           
    # All variants that have 'Review' tag                                                                              
    review_all_variant_ids = VariantTag.objects.filter(variant_tag_type__name='Review') \                              
            .values_list('saved_variant_id', flat=True)                                                                
    # Intersection of the previous two queries                                                                         
    review_variant_ids = single_variant_ids.intersection(review_all_variant_ids)

这不起作用给我一个错误:

ProgrammingError: each INTERSECT query must have the same number of columns LINE 1: ...nttag"."saved_variant_id") = 1) INTERSECT (SELECT "seqr_vari...

如何在 Django 中编写这样的查询?

Update

我使用了 Omar 的建议,并且能够通过像这样重写第二个查询来消除错误:

review_all_variant_ids = VariantTag.objects.filter(variant_tag_type__name='Review') \                              
                .values_list('saved_variant_id', flat=True).annotate(val=Value(0, output_field=IntegerField()))  

然而,intersection 没有正确计算交集,而是返回空的 QuerySet。我检查了 QuerySets 将它们转换为 python lists 并打印出来,这是我看到的:

single_variant_ids: [46, 28, 38, 30, 33, 29, 47, 31, 44]
review_all_variant_ids: [22, 36, 46, 47]
review_variant_ids: []

如您所见,交集结果不应为空,而应为 QuerySet,其值为:4647。我也试过这样写交集:

single_variant_ids & review_all_variant_ids 

但是报错:

TypeError: Merging 'QuerySet' classes must involve the same values in each case.

Update

我改了第二个空栏的名字QuerySet:

review_all_variant_ids = VariantTag.objects.filter(variant_tag_type__name='Review') \                              
                .values_list('saved_variant_id', flat=True).annotate(id_count=Value(0, output_field=IntegerField()))

之后执行以下操作:

review_variant_ids = single_variant_ids & review_all_variant_ids

但是结果是错误的:

[22, 36, 46, 47]

所以,交集在这里以错误的方式执行,不是我需要的。当然,最简单的方法就是将 QuerySets 都转换为 python sets 并计算它们的交集,但我想避免在最后一点之前查询数据库。

最初,您用 id_count 注释了第一个查询,这意味着它将成为查询结果中的一列,第二个查询中不存在该列,您可能只想注释它作为 Value(0) 在相交时保持列一致。

完成后,您现在可以尝试在交叉路口进行初始尝试,或者您可以尝试此过滤器:

single_variant_ids.filter(saved_variant_id__in=review_all_variant_ids.values_list('saved_variant_id'))

祝一切顺利