1

我有一个自我引用的多对多关系,如下所示:

class User(models.Model):
    groups = models.ManyToManyField('self', blank=True, null=True)

当我在用户 1 和用户 2 之间创建关系时,这是双向的。我可以看到这个:

User_1_obj.groups.all()
User_2_obj.groups.all()

但是,当我使用以下方法将用户 3 添加到关系中时:

User_1_obj.groups.add(User_3_obj) 

用户 1 和用户 3 是双向链接的。但我也希望用户 2 和用户 3(以及要链接的关系中的任何其他用户)。换句话说,我希望所有排列都相互关联,其中:

User 1 linked to User 2, User 3, User 4
User 2 linked to User 1, User 3, User 4
User 3 linked to User 1, User 2, User 4
User 4 linked to User 1, User 2, User 3

有没有比遍历所有链接并添加缺少的连接更简单的方法?

谢谢!感谢所有帮助。

4

2 回答 2

0

我认为您在错误的情况下使用了自我参照关系。如果您尝试创建用户之间的任意无向连接图,则自引用关系很有用。

如果连接到用户意味着您自动连接到所有其他用户,并且所有这些连接在语义上是完全等效的,那么在我看来,您正在尝试定义更像具有完整 连接组件的图形的东西。如果是这样的话,那么每个用户实际上只能属于一个组。

可以使用您的方案来做到这一点,但正如您所看到的,这将需要大量的手动管理来强制执行您的完全连接条件,过度描述。朝着更好的方向迈出的一步是通过对一个简单的字段进行分组,比如一个可为空的 IntegerField。

class User(models.Model):
    group = models.IntegerField(null=True)

然后,您可以查询与给定的同一组中的所有用户myUserby User.objects.filter(group=myUser.group)。唯一棘手的部分是,如果以前未连接的组中的两个用户连接起来,您将不得不立即为一组用户重新分配组。但是您可以进行批量更新以将第二组中的所有用户重新分配给第一个组,从而合并组。

但是,您需要问自己的一个问题是,用户与同一组中的任何其他用户断开连接是否会导致该用户与该组中的所有用户断开连接。

于 2012-11-25T03:48:21.713 回答
0

如果您的目标是获取所有其他用户,不包括您已经拥有的实例,那么这将起到作用:

class User(models.Model):
    def groups(self):
        return User.objects.exclude(pk=self.pk)

但是,如果您只想搜索User实例的子集,您可以创建第二个模型,称为Group. (这一切似乎有点傲慢,因为我们现在基本上是在复制django.contib.auth.models。)

class Group(models.Model):
    # Some attributes you would like (maybe a name, or code)

class User(models.Model):
    groups = models.ManyToManyField(Group, related_name='users')

    def get_linked_users(self, group):
        return group.users.exclude(pk=self.pk)

您想要实现的定义过于模糊,但这些是表示 Django 中实例之间关系的几种方法。


但是,我不确定是否应该在数据库中表示排列。我只会检索User我希望包含的所有对象,并在事后用 Python 计算出排列。

也许您可以更详细地了解这次尝试背后的原因。也许有更简单的方法。

于 2012-11-25T17:58:18.183 回答