Django中通过外键字段B.name去重报错的解决方法
问题描述
在如下Django模型关系中,如何针对关联模型B的字段实现去重?
class A(models.Model): b = models.ForeignKey("B") class B(models.Model): name = models.CharField(max_length=1024)
执行以下代码会报错:
A.objects.distinct('b__name')
报错信息:
django.db.utils.ProgrammingError: SELECT DISTINCT ON 表达式必须与初始 ORDER BY 表达式匹配 LINE 1: SELECT DISTINCT ON ("b"."name") "a"."id", ...
解决方案
这个报错源于PostgreSQL的DISTINCT ON语法规则:使用该语法时,必须先按指定的字段进行排序。以下是几种可行的解决方式:
方式一:先排序再去重
先对b__name字段排序,再执行distinct操作,满足语法要求的同时获取去重后的A对象:A.objects.order_by('b__name').distinct('b__name')注:该方式会返回每个唯一
b__name对应的第一个A对象(按排序后的顺序)。方式二:仅获取去重的字段值
如果只需要唯一的b__name值,不需要完整的A对象实例,可以结合values()和distinct():A.objects.values('b__name').distinct()执行后会返回字典列表,每个字典包含一个唯一的
b__name值。方式三:直接从B模型查询
既然name是B模型的原生字段,直接从B模型出发查询去重的name会更高效:# 仅获取去重的name值 B.objects.values('name').distinct() # 如果需要关联对应的A对象,可使用反向关联预取 B.objects.distinct('name').prefetch_related('a_set')
内容的提问来源于stack exchange,提问作者y.dai
相关产品推荐
相关产品推荐

