Django多对多关系排列关系

时间:2012-11-23 21:01:11

标签: django django-models

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

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

是否有更简单的方法来迭代所有链接并添加缺少的连接?

谢谢!感谢所有帮助。

2 个答案:

答案 0 :(得分:0)

我认为你在错误的情况下使用自我指涉关系。如果您尝试使用用户之间的任意无向连接图,则自引用关系非常有用。

如果连接到用户意味着您自动连接到所有其他用户,并且所有这些连接在语义上完全等效,那么在我看来,您尝试使用{{来定义更像图形的内容3}} complete。如果是这种情况,那么每个用户实际上只能属于一个组。

可以对您的方案执行此操作,但正如您所看到的,这将需要大量的手动管理来强制执行完全连接的条件,过于描述性。通过对一个简单的字段进行分组(如可以为空的IntegerField),可以在更好的方向上迈出一步。

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

然后,您可以myUser查询同一组中与给定User.objects.filter(group=myUser.group)相同的所有用户。唯一棘手的部分是,如果以前未连接的组中的两个用户连接,则必须立即为一堆用户重新分配组。但您可以执行connected components将第二组中的所有用户重新分配给第一组,以合并这些组。

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

答案 1 :(得分: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来计算排列后的排列。

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