我正在编写一个具有 People 模型的 Django 应用程序,但我遇到了一个障碍。我正在使用多对多关系将 Role 对象分配给人们 - 其中 Roles 有一个名称和一个权重。我希望按照最重角色的权重对我的人员列表进行排序。如果我执行 People.objects.order_by('-roles__weight'),那么当人们分配给他们多个角色时,我会得到重复。
我最初的想法是添加一个称为最重角色权重的非规范化字段 - 并以此排序。每次向用户添加或删除新角色时,这都可以更新。但是,事实证明,每次在 Django 中更新 ManyToManyField 时,都无法执行自定义操作(无论如何, yet )。
所以,我想我可以完全过火并编写一个自定义字段、描述符和管理器来处理这个问题 - 但是当为 ManyToManyField 动态创建 ManyRelatedManager 时,这似乎非常困难。
我一直在尝试想出一些可以为我做到这一点的聪明的 SQL - 我确信可以使用子查询(或几个),但我担心它不兼容所有数据库后端 Django支持。
有没有人以前做过这个 - 或者有任何想法如何实现?
最佳答案
Django 1.1(目前是测试版)添加了 aggregation支持。您的查询可以通过以下方式完成:
from django.db.models import Max
People.objects.annotate(max_weight=Max('roles__weight')).order_by('-max_weight')
这将按最重要的角色对人员进行排序,而不会返回重复项。
生成的查询是:
SELECT people.id, people.name, MAX(role.weight) AS max_weight
FROM people LEFT OUTER JOIN people_roles ON (people.id = people_roles.people_id)
LEFT OUTER JOIN role ON (people_roles.role_id = role.id)
GROUP BY people.id, people.name
ORDER BY max_weight DESC
关于sql - Django:按多对多字段订购模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/934779/