为何带annotate、order_by、distinct的Django QuerySet调用values报错?
问题原因解析
第一段代码正常运行的逻辑
这段代码的执行流程完全符合Django ORM的规则:
- 先通过
filter筛选出包含指定关键词的Order记录; - 用
annotate生成一个名为part_description_lower的注释字段(把part_description转换为小写); - 基于这个注释字段和
pk做排序; - 最后以
part_description_lower为依据去重。
整个过程中,part_description_lower始终作为查询的一部分被保留,order_by和distinct都能正常引用这个注释字段,最终返回完整的Order模型实例查询集,因此可以正常运行。
第二段代码报错的核心原因
问题出在最后新增的.values('pk')方法:
在Django ORM中,values()会强制限定查询返回的字段范围——只有被明确写在values()参数里的字段(包括注释字段),才会被保留在后续的查询逻辑中。这里你只指定了pk,导致之前通过annotate生成的part_description_lower被排除在查询字段之外。
但前面的distinct("part_description_lower")必须依赖这个注释字段才能完成去重逻辑,Django在构建查询时找不到这个字段,就会抛出Cannot resolve keyword 'part_description_lower' into field的错误。
修复思路(可选)
如果需要保留values方法并正常运行,需要把注释字段也加入values的参数列表,比如:
Order.objects.filter(part_description__icontains=search_query) .annotate(part_description_lower=Lower('part_description')) .order_by("part_description_lower", '-pk') .distinct("part_description_lower") .values('pk', 'part_description_lower')
这样Django就能找到去重所需的字段,不过返回结果会包含这两个字段的字典,需根据实际需求调整。
内容的提问来源于stack exchange,提问作者Nicola Zilio
相关产品推荐
相关产品推荐

