嗯,没有直接的方法,但在我看来,这可能有效。
只有当您要添加的成员存在于其他团队中时,一组成员与另一个团队成员发生冲突的唯一可能性,所以首先我们需要获取那些已经添加用户的团队:
# fetch teams where user is already added
teams = Team.objects.filter(members__id=user.id)
will_clash = False
if teams:
# prepare list of tuples of sorted members id for each team
members_set = [tuple(team.members.values_list('id', flat=True).order_by('id')) for team in teams]
# we know already in which team we want to add lets say it is `team_c`
team_c_members_set = tuple(sorted(list(team_c.members.values_list('id', flat=True)) + [user.id]))
if team_c_members_set in members_set:
# adding current `user` is going to create a clash
will_clash = True
if not will_clash:
# all good lets add the user in team
team_c.members.add(user)
试运行:
假设您有以下三个团队:
Team A:
1: member
2: member
3: member
Team B:
1: member
2: member
4: member
Team C:
3: member
2: member
现在我们想将成员 id: 1 添加到团队 C。应该避免这种情况,因为这将创建与团队 A 相同的用户集,让我们运行上面的代码来查看是否是 True:
# fetch teams where user is already added
teams = [A, B] # user already there
# prepare list of tuples of sorted members id for each team
members_set = [(1, 2, 3), (1, 2, 4)]
# we know already in which team we want to add lets say it is `team_c` so it will become
team_c_members_set = (1, 2, 3) # tuple(sorted([3, 2] + [1]))
team_c_members_set in members_set # <-- True
一次添加完整团队的场景
假设您要立即添加完整团队 C,因此您已经知道该团队中将拥有哪些成员,在这种情况下,过程几乎相似,但首先创建 team_c_members_set 以用于过滤 @987654330 @:
users_to_add = [user_a, user_b, user_c]
team_c_members_set = tuple(sorted([u.id for u in users_to_add])
teams = Team.objects.filter(members__id__in=team_c_members_set).distinct()
will_clash = False
if teams:
# prepare list of tuples of sorted members id for each team
members_set = [tuple(team.members.values_list('id', flat=True).order_by('id')) for team in teams]
if team_c_members_set in members_set:
will_clash = True
if not will_clash:
# all good lets add the users in team
team_c.members.add(*users_to_add)