Mri*_*lla 6 python django django-orm
我在Django中有两个模型由ManyToMany关联链接在一起,如下所示:
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person)
Run Code Online (Sandbox Code Playgroud)
我需要让小组中的主要人物成为小组中的第一个人.我怎样才能得到第一个人?
这是我添加成员的方式:
grp = Group.objects.create(name="Group 1")
grp.save()
prs = Person.objects.create(name="Tom")
grp.members.add(prs) #This is the main person of the group.
prs = Person.objects.create(name="Dick")
grp.members.add(prs)
prs = Person.objects.create(name="Harry")
grp.members.add(prs)
Run Code Online (Sandbox Code Playgroud)
我不认为我需要任何额外的列,因为表的id group_members是正确的运行序列.
如果我尝试获取组中的主要成员,Group.objects.get(id=1).members[0]那么Django说管理器不可索引.
如果我试试这个Group.objects.get(id=1).members.all().order_by('id')[0],我会得到Person表中id最低的成员.
我怎么解决这个问题?
谢谢
Django没有注意调用的顺序add.Django对于关系的隐式表是如下所示,如果它是Django模型:
class GroupMembers(models.Model):
group = models.ForeignKey(Group)
person = models.ForeignKey(Person)
Run Code Online (Sandbox Code Playgroud)
显然,没有什么关于"订单"或者你应该先来的.默认情况下,它可能会按照您描述的方式执行并返回最低的pk,但这只是因为它没有任何其他内容可以消除.
如果要强制执行订单,则必须使用直通表.基本上,不是让Django创建隐式模型,而是自己创建它.然后,您将添加一个字段order来指示顺序:
class GroupMembers(models.Model):
class Meta:
ordering = ['order']
group = models.ForeignKey(Group)
person = models.ForeignKey(Person)
order = models.PositiveIntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
然后,你告诉Django使用这个模型的关系,而不是:
class GroupMembers(models.Model):
group = models.ForeignKey(Group)
person = models.ForeignKey(Person, through='GroupMembers')
Run Code Online (Sandbox Code Playgroud)
现在,当您添加成员时,您将无法再使用add,因为需要其他信息才能完成关系.相反,您必须使用直通模型:
prs = Person.objects.create(name="Tom")
GroupMembers.objects.create(person=prs, group=grp, order=1)
prs = Person.objects.create(name="Dick")
GroupMembers.objects.create(person=prs, group=grp, order=2)
prs = Person.objects.create(name="Harry")
GroupMembers.objects.create(person=prs, group=grp, order=3)
Run Code Online (Sandbox Code Playgroud)
然后,只需使用:
Group.objects.get(id=1).members.all()[0]
Run Code Online (Sandbox Code Playgroud)
或者,您只需添加一个BooleanField指定哪个是主要用户:
class GroupMembers(models.Model):
group = models.ForeignKey(Group)
person = models.ForeignKey(Person)
is_main_user = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)
然后,添加"Tom",如:
prs = Person.objects.create(name="Tom")
GroupMembers.objects.create(person=prs, group=grp, is_main_user=True)
Run Code Online (Sandbox Code Playgroud)
最后,通过以下方式检索"Tom":
Group.objects.get(id=1).members.filter(is_main_user=True)[0]
Run Code Online (Sandbox Code Playgroud)