Подтвердить что ты не робот

Django - использование уникальных элементов ManyToManyField

Я пытаюсь сделать что-то простое:

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() терпеть неудачу? Должен ли я просто проверить, содержится ли пользователь уже перед добавлением?

Спасибо!

4b9b3361

Ответ 1

Во-первых, я бы не использовал num_members. Вместо этого вы можете проверить, сколько членов есть с mygroup.members.count(). Во-вторых, добавление элементов несколько раз не добавляет их более одного раза, так что вы в порядке.

A ManyToManyField в Group для member, указывающий на User, реализуется с отдельной таблицей (например, group_group_users), которая имеет внешний ключ для Group и User. Пользователь может иметь несколько групп, а группа может иметь несколько пользователей, но не может быть двух строк в group_group_users для одного и того же отношения (т.е. Уникальных вместе внешних ключей).

Использование:

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

Ответ 2

Повторяющиеся пользователи не отображаются в утилите администратора.

Они не созданы.

Не удается ли добавить() с ошибкой?

Да.

Должен ли я просто проверить, содержит ли пользователь уже до добавления?

Да. Или вместо ручного подсчета пользователей вы можете просто подсчитать количество баз данных:

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

Это устраняет необходимость в поле num_members в реальной модели.

Кроме того, вы не должны использовать id в качестве имени параметра для своей функции.