Django - 强制执行ManyToManyField唯一项

JPC*_*JPC 24 python django django-models

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

members = models.ManyToManyField(User,blank=True,null=True,unique=True)
Run Code Online (Sandbox Code Playgroud)

但不允许有独特之处.在查看创建的表时,它会使外键如此独特,这是我想象的.

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

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

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

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

谢谢!

oro*_*aki 30

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

ManyToManyFieldGroup用于member指向User与一个单独的表(类似于实施group_group_users具有外键)GroupUser.用户可以有多个组,一个组可以有多个用户,但是group_group_users对于相同的关系,不能有两行(即,唯一的外键一起).

用法:

>>> group = Group.objects.get(pk=1)
>>> user = User.objects.get(pk=1)
>>> group.members.add(user)
>>> # Worked fine as expected. Let's check the results.
>>> group.members.all()
[<User: foousername>]
>>> group.members.add(user)
>>> # Worked fine again. Let's check for duplicates.
>>> group.members.all()
[<User: foousername>]
>>> # Worked fine.
Run Code Online (Sandbox Code Playgroud)


Mik*_*one 15

重复的用户不会出现在管理实用程序中.

它们不是被创造出来的.

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

是.

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

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

mygroup = Group.objects.filter(...).annotate(num_members=models.Count("members"))
Run Code Online (Sandbox Code Playgroud)

这消除了num_members对实际模型中的字段的需要.

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