python Django 多对多关系,并通过

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1307548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:54:33  来源:igfitidea点击:

Django many-to-many relations, and through

pythondjangoforeign-keysmany-to-many

提问by Jiaaro

I want to store which user invited another user to a group... but django is telling me this is ambigous and against the rules (which makes sense).

我想存储哪个用户邀请另一个用户加入一个组......但 django 告诉我这是模棱两可的并且违反规则(这是有道理的)。

groups.group: Intermediary model Group_to_Member has more than one foreign key to User, which is ambiguous and is not permitted.

groups.group:中介模型Group_to_Member 有多个外键给User,这是不明确的,是不允许的。

So how do I do this correctly? Maybe a generic relation? might work but seems a bit convoluted... Here's how I was approaching it (with unrelated bits removed)

那么我该如何正确地做到这一点呢?也许是泛型关系?可能有用,但似乎有点复杂……这是我的处理方式(删除了无关的部分)

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")

Solution

解决方案

Ok so I did a little combination of the answers you guys provided (Thanks!) and things I found on the internet plus my own admittedly meager python-fu:

好的,所以我结合了你们提供的答案(谢谢!)和我在互联网上找到的东西以及我自己公认的微薄的 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")

采纳答案by Graham King

You have to manage it yourself:

您必须自己管理:

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')

Then instead of group.members.all()you do group.membership_set.all().

然后代替group.members.all()你做group.membership_set.all()

Also, I wouldn't use 'Group' as your model name, as Django already has a Group object.

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

回答by Mauricio Abreu

It is possible if you are using Django 1.7.

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

From the docs: https://docs.djangoproject.com/en/1.7/topics/db/models/#extra-fields-on-many-to-many-relationships

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

In Django 1.6 and earlier, intermediate models containing more than one foreign key to any of the models involved in the many-to-many relationship used to be prohibited.

在 Django 1.6 及更早版本中,包含多个外键的中间模型曾经被禁止用于多对多关系中涉及的任何模型。