Django - 强制执行ManyToManyField唯一项

时间:2011-02-02 05:00:18

标签: python django django-models

我正在尝试做这样简单的事情:

members = models.ManyToManyField(User,blank=True,null=True,unique=True)

但不允许使用唯一身份。在查看创建的表时,它会使外键如此独特,这是我想象的。

我希望能够将成员与代表组的此模型相关联。该组可以没有成员,但我不希望同一成员能够两次加入该组。

我的想法是,如果我尝试这样做会抛出异常,但似乎没有抛出异常。

def join(request,id):
    user = request.user
    mygroup = Group.objects.get(id=id)
    mygroup.members.add(user)
    mygroup.num_members+=1
    mygroup.save()

num_members递增,因为不会抛出异常。重复的用户不会出现在管理实用程序中。 add()是否会无声地失败?我应该只是在添加之前检查用户是否已被包含?

谢谢!

2 个答案:

答案 0 :(得分:28)

首先,我不会使用num_members。相反,您可以使用mygroup.members.count()检查有多少成员。其次,多次添加成员并不会真正添加多次,所以你没事。

指向ManyToManyField的{​​{1}} Group member使用单独的表(类似User)实现,该表具有group_group_users的外键{1}}和Group。用户可以拥有多个组,一个组可以拥有多个用户,但User中不能有两行用于相同的关系(即,唯一的外键一起)。

用法:

group_group_users

答案 1 :(得分:15)

  

重复用户未显示在管理实用程序中。

他们没有被创造。

  

add()是否会无声地失败?

  

我应该只是在添加之前检查用户是否已被包含?

是。或者不是手动计算用户数,而是可以为您计算数据库:

mygroup = Group.objects.filter(...).annotate(num_members=models.Count("members"))

这样就无需在实际模型中使用num_members字段。

此外,您不应将id用作函数的参数名称。