回答

收藏

Django:通过多对多字段订购模型

技术问答 技术问答 328 人阅读 | 0 人回复 | 2023-09-14

我正在写一个People模型的Django应用程序,但遇到了麻烦。我用多对多关系将角色对象分配给人们。-
! W- e; E7 z; V, i) s8 B角色有名字和权重。我想按照角色最重的顺序安排我的人员清单。如果我执行,People.objects.order_by(’-roles__weight’),所以当人们被分配多个角色时,我会被重复。
0 R. [2 c; V9 Q) P! k( N我最初的想法是加一个叫 的角色权重最重    非标准化字段-
, r; @, p/ ]3 l1 e3 A并进行排序。每次添加新角色或从用户删除新角色时,都可以更新此信息。然而,事实证明,是否有办法每次执行自定义操作ManyToManyField是在Django(更新时间还没有,反正)。% z9 q( C$ H6 h- j) |
因此,我认为我可以完全放弃,写一个自定义的字段,描述符和管理器来处理这个问题,但作为ManyToManyField动态创建ManyRelatedManager这似乎很难。
7 o% @# h! M- F  x我一直在努力提出一些聪明的东西SQL能为我做到这一点-我可以保证子查询(或几个子查询)是可能的,但我担心它与所有数据库的后端Django支持不兼容。' P3 v' C* p9 N
有人做过吗?还是对如何实现有什么想法?
, V* F6 o  L0 ]* ]                                                                6 ^: {2 H) m; t/ [
    解决方案:                                                               
0 p" n% ]. `" \  W                                                                Django
: e3 N/ J3 c" p+ G: O1.1(当前为beta)增加了对聚合的支持。您的查询可以通过以下方式完成:
( H; H, g; ~# P% V2 Dfrom django.db.models import MaxPeople.objects.annotate(max_weight=Max('roles__weight')).order_by('-max_weight')这样,人员就可以在不返回重复项的情况下按照最重的角色进行排序。
& T# P- e- O% \9 k3 T2 k& A4 n* d生成的查询为:
* \, `& m0 Q1 [9 o* A& g5 S; i0 s, `SELECT people.id,people.name,MAX(role.weight) AS max_weightFROM 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.nameORDER BY max_weight DESC
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则