无法获取Django ManyToMany模型对象的句柄
我在一个Django应用里有一个简单的例子,涉及到一个会员(Member)和一个会员组(MemberGroup)类。我想要这样的数据表示,但不确定使用多对多关系(ManyToMany)是否让事情变得复杂了:
会员:
1 - 会员1
2 - 会员2
3 - 会员3
组:
1 - 组1
2 - 组2
3 - 组3
会员组:
1 - 会员1/组1
2 - 会员1/组2
3 - 会员2/组3,等等。
我有以下这些类:
class Member(models.Model):
nickname = models.CharField(max_length=30, blank=False)
paid = models.BooleanField(default=False)
class MemberGroup(models.Model):
member = models.ManyToManyField(Member)
group_name = models.CharField(max_length=50, db_index=True)
description = models.CharField(max_length=255)
我希望能在其他模型类中使用id/会员/组的组合(比如在BlogPost类中用MemberGroupId和帖子内容),但我不太确定怎么才能获取到那个特定的对象。现在的模型能生成正确的数据库表,但我不太清楚怎么获取代表链接表的对象。在Django的命令行界面中,当我获取MemberGroup(id=1)并尝试打印与这个MemberGroup关联的会员时,我得到的结果是:
<django.db.models.fields.related.ManyRelatedManager object at 0x2ae6c10>
我需要创建另一个类,组(Group),然后让会员和组在会员组类中作为外键吗?这样才能实现我想要的功能,还是我可以继续用现在的设置?谢谢任何帮助!
2 个回答
首先,我会这样创建模型:
from django.db import models
class Group(models.Model):
group_name = models.CharField(max_length=50, db_index=True)
description = models.CharField(max_length=255)
class Member(models.Model):
nickname = models.CharField(max_length=30, blank=False)
paid = models.BooleanField(default=False)
groups = models.ManyToManyField(Group)
然后你可以这样做:
>>> test_group = Group(group_name='Admin', description='Admin group')
>>> test_group.save()
>>> m1 = Member(nickname='Robert')
>>> m1.save()
>>> m1.groups.add(test_group)
>>> m1.save()
>>> m1.groups.all()
[<Group: Group object>]
>>> test_group.objects.get(group_name='Admin').member_set.all()
[<Member: Member object>]
这段代码创建了一个名为“Admin”的组,然后添加了一个成员“Robert”。它把“Robert”这个用户和“Admin”组关联起来。接着,我可以通过 member_set
来获取“Admin”组的所有成员。
补充说明:把 ManyToMany
字段放在 Group
模型里来指向成员其实没有什么问题,但在我看来,把成员和组关联起来似乎更合理,而不是把组和成员关联起来。
所以我又看了一遍关于多对多关系的文档,找到了正确的解决办法,就是在模型上使用这个“through”的设置。现在我的模型看起来是这样的:
class Member(models.Model):
nickname = models.CharField(max_length=30, blank=False)
paid = models.BooleanField(default=False)
class Group(models.Model):
group_name = models.CharField(max_length=50, db_index=True)
description = models.CharField(max_length=255)
created_by = models.ForeignKey('Member', related_name='created_by')
created_date = models.DateTimeField(auto_now=True)
members = models.ManyToManyField(Member, through="Membership")
def __unicode__(self):
return self.group_name
class Membership(models.Model):
member = models.ForeignKey(Member)
group = models.ForeignKey(Group)
active = models.BooleanField(default=True, db_index=True)
join_date = models.DateTimeField(auto_now=True)
league_manager = models.BooleanField(default=False, db_index=True)
def __unicode__(self):
return "%s (%s)" % (self.member, self.group)
现在我可以直接使用Membership这个类了,而之前虽然建立了关系,但没有明确的对象可以使用。谢谢大家。