Django外键关联查询按外键分组取单条去重记录实现
问题原因
你当前使用的distinct()是基于Binomiale表主键去重,而非按关联的Famille(科)外键去重。由于同一个科下对应多条物种(Binomiale)记录,查询自然会返回重复的科分类条目。
可行解决方案
推荐使用兼容所有数据库(包括你当前用的SQLite)的通用实现,模板代码无需任何修改即可正常渲染。
1. 修改视图层查询逻辑
替换你视图中非搜索场景下的原有查询代码:
# 原有错误代码可删除 # famille_list1 = Binomiale.objects.select_related("famille").distinct().order_by("famille__famille_name")[:12] famille_list1 = [] # 先取按名称排序、且存在对应物种记录的前12个科 familles = Famille.objects.filter( famille_names__isnull=False ).distinct().order_by('famille_name')[:12] # 为每个科取第一条关联物种作为展示样本 for famille in familles: sample_species = famille.famille_names.order_by('nom').first() if sample_species: famille_list1.append(sample_species)
你的
Binomiale模型中Famille外键已经定义了related_name='famille_names',所以可以直接通过famille.famille_names反向取关联的物种记录。
2. 可选高性能方案(仅适用于PostgreSQL)
如果后续迁移到PostgreSQL数据库,可以用单条查询完成逻辑,不需要循环查询,性能更高:
famille_list1 = Binomiale.objects.select_related("famille").filter( famille__isnull=False ).distinct('famille').order_by('famille__famille_name', 'nom')[:12]
注意:该写法要求order_by的第一个字段必须和distinct()传入的字段一致,否则会抛出语法错误。
原有代码其他问题修复
- 未登录用户访问非搜索页面时,
famille_list1变量未定义会直接报错,建议补全未登录场景的逻辑,比如返回公开数据或者重定向到登录页。 - 搜索分支的查询条件重复添加了两次相同的过滤规则,属于冗余代码,可以删除重复的
query.add(...)行。
内容的提问来源于stack exchange,提问作者smebird
相关产品推荐
相关产品推荐

