如何在多对多字段(完全匹配)中通过其对象过滤django模型?

Sni*_*irD 14 django many-to-many django-models django-orm

我的代码中有这个模型:

class Conversation(models.Model):
    participants = models.ManyToManyField(User, related_name="message_participants")
Run Code Online (Sandbox Code Playgroud)

我需要通过"参与者"多对多字段过滤这个"对话"模型对象.意思是:我有3个用户对象,所以我想检索唯一的"对话"对象,其中有3个用户在其"参与者"字段中.

我试过这样做:

def get_exist_conv_or_none(sender,recipients):
    conv = Conversation.objects.filter(participants=sender)
    for rec in recipients:
        conv = conv.filter(participants=rec)
Run Code Online (Sandbox Code Playgroud)

其中sender是User对象,"recipients"是User对象列表.它不会引发错误,但它给了我错误的对话对象.谢谢.

编辑:最近的一次尝试引导我:

def get_exist_conv_or_none(sender,recipients):
    participants=recipients
    participants.append(sender)
    conv = Conversation.objects.filter(participants__in=participants)
    return conv
Run Code Online (Sandbox Code Playgroud)

这基本上有同样的问题.它产生的对象在列表中有一个或多个"参与者".但我正在寻找的是多对多对象的精确匹配.意思是,一个具有确切"用户"的对象是多对多关系.

编辑2:我的最后一次尝试.仍然,不会工作.

def get_exist_conv_or_none(sender,recipients):
    recipients.append(sender)
    recipients = list(set(recipients))
    conv = Conversation.objects.annotate(count=Count('participants')).filter(participants=recipients[0])
    for participant in recipients[1:]:
        conv.filter(participants=participant)
    conv.filter(count=len(recipients))
    return conv
Run Code Online (Sandbox Code Playgroud)

Sni*_*irD 7

好的,我找到了答案:为了完全匹配,我必须对模型进行链式过滤,然后确保它具有所需的确切数量的参数,以便多对多字段将具有它需要的所有物品,而不是更多.

我将使用注释检查对象编号:(https://docs.djangoproject.com/en/dev/topics/db/aggregation/)

结束了这段代码:

def get_exist_conv_or_none(recipients):
    conv = Conversation.objects.annotate(count=Count('participants')).filter(participants=recipients[0])
    for participant in recipients[1:]:
        conv = conv.filter(participants=participant)
    conv = conv.filter(count=len(recipients))
    return conv
Run Code Online (Sandbox Code Playgroud)