代码之家  ›  专栏  ›  技术社区  ›  Jiaaro

Django多对多关系,并通过

  •  10
  • Jiaaro  · 技术社区  · 15 年前

    我要存储哪个用户邀请了另一个用户加入组…但Django告诉我这是矛盾的,违反了规则(这是有道理的)。

    groups.group:中介模型 组成员有多个 用户的外键,即 不明确,不允许。

    那么,我如何正确地做到这一点呢?可能是一般关系?可能有效,但似乎有点复杂…以下是我接近它的方式(去掉无关的部分)

    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 Fu:

    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 回复  |  直到 15 年前
        1
  •  8
  •   Graham King ptim    15 年前

    你必须自己管理它:

    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.members.all() 你做 group.membership_set.all() .

    另外,我不会使用“group”作为模型名,因为django已经有了一个group对象。

        2
  •  0
  •   Mauricio Abreu    10 年前

    如果您使用的是Django 1.7,这是可能的。

    来自文档: https://docs.djangoproject.com/en/1.7/topics/db/models/#extra-fields-on-many-to-many-relationships

    在Django 1.6及更早版本中,中间模型包含超过 多对多模型中涉及的任何模型的一个外键 以前是禁止的关系。