如何通过其在多对多字段中的对象(完全匹配)过滤 django 模型? [英] How to filter django model by its objects in many-to-many field (exact match)?

查看:33
本文介绍了如何通过其在多对多字段中的对象(完全匹配)过滤 django 模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码中有这个模型:

I have this model in my code:

class Conversation(models.Model):
    participants = models.ManyToManyField(User, related_name="message_participants")

我需要通过参与者"多对多字段过滤这个对话"模型对象.含义:例如,我有 3 个用户对象,因此我想检索在参与者"字段中包含这 3 个用户的唯一对话"对象.

and I need to filter this "Conversation" model objects by the "participants" many-to-many field. meaning: I have for example 3 User objects, so I want to retrieve the only "Conversation" objects that has this 3 Users in it's "participants" field.

我尝试这样做:

def get_exist_conv_or_none(sender,recipients):
    conv = Conversation.objects.filter(participants=sender)
    for rec in recipients:
        conv = conv.filter(participants=rec)

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

where sender is a User object and "recipients" is a list of User objects. it won't raise error but it gives me the wrong Object of Conversation. Thanks.

最近的一次尝试使我想到了这一点:

edit: A more recent try lead me to this:

def get_exist_conv_or_none(sender,recipients):
    participants=recipients
    participants.append(sender)
    conv = Conversation.objects.filter(participants__in=participants)
    return conv

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

which basically have the same problem. It yields Objects which has one or more of the "participants" on the list. but what Im looking for is exact match of the many-to-many object. Meaning, an Object with the exact "Users" on it's many-to-many relation.

编辑 2:我的最后一次尝试.还是不行.

edit 2: My last attempt. still, won't work.

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

推荐答案

好的,我找到了答案:为了进行精确匹配,我必须对模型进行链式过滤,然后确保它具有所需的确切参数数量,以便多对多字段中包含全部 需要的对象,仅此而已.

Ok so I found the answer: In order to make an exact match I have to chain-filter the model and then make sure it has the exact number of arguments it needs to have, so that the many-to-many field will have in it all the objects needed and no more.

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

I will check for the objects number using annotation: ( 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

这篇关于如何通过其在多对多字段中的对象(完全匹配)过滤 django 模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆