使用 Django ManyToManyField 检查实例是否存在

Check the existence of instance with Django ManyToManyField

大家好!

如何使用ManyToManyField()检查数据库中是否已存在类似记录:

class Room():
     created_by = models.ForeignKey(User)
     allowed_users = models.ManyToMany(User,related_name='rooms_as_guest')
     is_active = models.BooleanField(default=True)

在我看来,在创建新房间之前,我想确保没有一个活动房间的参与者完全相同。

下面的例子是行不通的,只是为了展示我所期望的

 allowed_users = User.objects.filter(id__in=request.POST.get("ids",[]))
 if allowed_users:
     Room.objects.get_or_create(
         created_by = request.user,
         allowed_users = allowed_users, # won't work
         is_active = True,
     )

我怎样才能继续做我想做的事?

您不能使用 ManyToMany 字段创建这样的对象,因为该对象必须存在才能创建代表您的 m2m 关系的中间对象。你必须做类似的事情:

allowed_users = User.objects.filter(id__in=request.POST.get("ids", [])).order_by('id')

room = None
for r in up.rooms.filter(is_active=True):
    if list(allowed_users) == list(r.allowed_users.all().order_by('id')):
        room = r # get the existing room
        break

if not room:
    room = Room.objects.create(
        created_by = request.user,
        is_active = True
    )
    room.allowed_users.add(*allowed_users)

您必须确保 allowed_users 与 room.allowed_users 的顺序相同。

Check the docs 了解更多信息

这是因为 allowed_users 是一个 ManyToMany 字段,因此,在向其中添加用户之前需要创建房间。

在此处查看官方文档: https://docs.djangoproject.com/en/2.1/topics/db/examples/many_to_many/#many-to-many-relationships

现在的另一个问题是我们需要获得一个拥有相同用户集的现有房间,这已在此处的类似问题中得到解答:

尝试以下:

from django.db.models import Count

allowed_users = User.objects.filter(id__in=request.POST.get("ids",[]))
if allowed_users:
    room = Room.objects.filter(allowed_users__in=allowed_users).annotate(num_users=Count('allowed_users')).filter(num_users=len(allowed_users)).first()
    if not room:
        room = Room.objects.create(created_by=request.user, is_active=True)
        room.allowed_users.add(*allowed_users)