Django "многие ко многим", и через

Я хочу сохранить, какой пользователь пригласил другого пользователя в группу... но django говорит мне, что это неоднозначно и противоречит правилам (что имеет смысл).

groups.group: Промежуточная модель Group_to_Member имеет более одного внешний ключ для пользователя, который неоднозначно и не допускается.

Итак, как мне это сделать правильно? Может быть, общее отношение? может работать, но кажется немного запутанным... Вот как я подходил к нему (с удалением несвязанных битов)

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

Ответ 1

Вам нужно самому управлять:

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

Возможно, если вы используете Django 1.7.

Из документов: https://docs.djangoproject.com/en/1.7/topics/db/models/#extra-fields-on-many-to-many-relationships

В Django 1.6 и ранее промежуточные модели, содержащие больше, чем один иностранный ключ к любой из моделей, участвующих во многих отношениях отношения были запрещены.