【发布时间】:2020-05-13 09:20:36
【问题描述】:
我有一个模型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:每个 INTERSECT 查询的列数必须相同 第 1 行:...nttag"."saved_variant_id") = 1) INTERSECT (SELECT "seqr_vari...
我如何在Django 中编写这样的查询?
更新
我使用了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,其值为:46 和 47。我也试着像这样写交集:
single_variant_ids & review_all_variant_ids
但它给出了一个错误:
TypeError:合并“QuerySet”类在每种情况下必须涉及相同的值。
更新
我把第二个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 注释了第一个,这意味着它将是查询结果中的一列,该列在第二个查询中不存在,您可能只想将其注释为相交时保持列一致的值(0)
-
太好了,快到了,您现在可以尝试在交叉路口进行初始尝试,也可以尝试以下过滤器:single_variant_ids .filter(saved_variant_id__in=review_all_variant_ids.values_list('saved_variant_id'))
-
是的,这就是答案。如果您发布答案,我会接受它
标签: django django-orm python-2.x