Django ManyToManyField 查询数据 按添加时间排序

在Django中,ManyToManyField是常用的Field,实现数据库中多对多模型。

例如,人和组之间的关系(一个人可以加入多个组,一个组有多个人):

[En]

For example, the relationship between people and groups (a person can join more than one group, a group has more than one person):

但是,当我们通过​ ​group.members​​​(或​ ​person.groups​​)获取一个组织的所有成员(或获取这个人参加的所有组织)时, 拿到的数据是按照group_id (或person_id)排列的,有时这样的行为不符合预期:

比如前端展示这个团体的人,希望是按照加入顺序来展示,而非按照人的id排序。

试想,当团队很大的时候,你加一个人,他没有出现在最后,但在一群人中间,你可能找不到他!我甚至怀疑我是否成功地添加了它。类似的场合屡见不鲜

[En]

Just imagine, when the team is very large, you add a person, he does not appear at the end, but in the middle of a group of people, you may not find him! I even wonder if I have succeeded in adding it. * similar occasions are common *

解决方案(无需改变数据库结构)

Django在实现ManyToManyField时,会默默引入一张”中间表”,它默认包括3列:​ ​id​​​、​ ​model1_id​​​、​ ​model2_id​​​。以上面的Person和Group为例,这3列就是:​ ​id​​​、​ ​person_id​​​、​ ​group_id​​​。这个​ ​id​​​是自增索引,当然也意味着:建立的时间晚,​ ​id​​​相对就大。我们可以通过​ ​id​​来实现”按添加时间排列”,而无需对数据库结构做任何改变!

为了实现这一点,我们需要适当地改变获取数据的方式:

[En]

In order to achieve this, the way we obtain data needs to be changed appropriately:

刚才提到,Django会默默引入一张”中间表”,这张”中间表”其实也是对应着一个隐藏的”Modal”的(生成顺序其实是Django先生成隐藏的Modal,再根据这个Modal生成那个数据库表)。​ ​Group.members.through​​​这句话其实是引用了那个隐藏的”Modal”。它后面的​ ​.objects​​,就像对待普通Modal一样,对待它就可以了。

在本文开头的例子,隐藏的”Modal”长这个样子:

它生成的数据库表就是3列:​ ​id​​​、​ ​person_id​​​、​ ​group_id​​。

其实,这张表你也可以自己定义出来,不让Django自动生成,只是你需要多提供一个参数​ ​throuth​​给ManyToManyField:

这里我们给中间表起了名字​ ​Membership​​​,名字随意起,​ ​through​​参数跟名字是对应的就行。

为什么through是写的字符串&#x200B;<strong>'Membership'</strong>&#x200B;,而非直接写&#x200B;<strong>Membership</strong>&#x200B;

因为Python解析器解析类的定义时,会把类的属性、方法都定义完,才会继续解析下一个类(在定义members时,​ &#x200B;Membership&#x200B;​尚未被解析,此时如果引用它会报错,所以Django面对这种问题的解决方案就是——先用字符串代替,这是很常见的做法)

Original: https://blog.51cto.com/hullqin/5562724
Author: HullQin
Title: Django ManyToManyField 查询数据 按添加时间排序

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/504311/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球