Django - enforcing ManyToManyField unique items
For one, I wouldn't use num_members
. Instead, you can check how many members there are with mygroup.members.count()
. Secondly, adding members more than once doesn't really add them more than once, so you're fine.
A ManyToManyField
on Group
for member
pointing to User
is implemented with a separate table (something like group_group_users
) which has a foreign key to Group
and User
. A user can have multiple groups, and a group can have multiple users, but there can't be two rows in group_group_users
for the same relationship (ie, unique together foreign keys).
Usage:
>>> 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.
Duplicate users don't appear in the admin utility.
They're not created.
Does add() fail silently?
Yes.
Should I just simply check if the user is contained already before adding?
Yes. Or instead of manually counting the users, you could just have the database count for you:
mygroup = Group.objects.filter(...).annotate(num_members=models.Count("members"))
This eliminates the need for a num_members
field in the actual model.
Also, you shouldn't use id
as a parameter name to your function.