Django 多对多关系及中介表
我想记录哪个用户邀请了另一个用户加入一个群组……但是Django告诉我这样做会产生歧义,并且不符合规则(这也说得通)。
groups.group: 中介模型 Group_to_Member对User有多个外键,这样会造成歧义,是不被允许的。
那么我该怎么正确地做呢?也许可以用通用关系?但感觉有点复杂……这是我之前的思路(去掉了一些无关的部分)
from django.contrib.auth.models import User
class UserGroup(models.Model):
members = models.ManyToManyField(User, through='Group_to_Member')
class UserGroup_to_Member(models.Model):
group = models.ForeignKey(UserGroup)
member = models.ForeignKey(User)
invited_by = models.ForeignKey(User, related_name="group_invited_users")
解决方案
好的,我结合了大家提供的答案(谢谢大家!)以及我在网上找到的一些资料,再加上我自己不太高明的Python技能,做了一些尝试:
from django.contrib.auth.models import User
class UserGroup(models.Model):
# notice there is no member object here
... other model data
def add_member(self, **kwargs):
g2m = UserGroup_to_Member(group = self, **kwargs)
g2m.save()
def remove_member(self, member):
g2m = UserGroup_to_Member.objects.get(group=self, member=member)
g2m.delete()
# This is not elegant at all, help please? I'm pretty sure it isn't
# as bad on the database as it looks though.
def get_members(self):
g2ms = UserGroup_to_Member.objects.filter(group=self)
member_ids = [g2m.member.id for g2m in g2ms]
members = User.objects.none()
for id in member_ids:
members = members | User.objects.get(id=id)
return members
class UserGroup_to_Member(models.Model):
group = models.ForeignKey(UserGroup)
member = models.ForeignKey(User)
invited_by = models.ForeignKey(User, related_name="group_invited_users")
2 个回答
1
如果你在使用Django 1.7的话,这是可能的。
根据文档:https://docs.djangoproject.com/en/1.7/topics/db/models/#extra-fields-on-many-to-many-relationships
在Django 1.6及之前的版本中,很多对很多的关系中,包含多个外键的中间模型是被禁止的。
9
你需要自己来管理这个:
class MyGroup(models.Model):
name = models.CharField(max_length=100)
class Membership(models.Model):
group = models.ForeignKey(MyGroup)
member = models.ForeignKey(User)
invited_by = models.ForeignKey(User, related_name='invited_set')
所以你应该用 group.membership_set.all()
来代替 group.members.all()
。
另外,我建议你不要把模型命名为 'Group',因为Django已经有一个叫做Group的对象了。