我有两个简单的模型:
class Message(BaseModel):
src = models.ForeignKey('Personne', related_name='message_src')
dst = models.ForeignKey('Personne', related_name='message_dst')
is_read = models.BooleanField(default=False)
message = models.TextField(null=True, blank=True,
verbose_name=_(u'Messages'))
class Conversation(BaseModel):
personnes = models.ManyToManyField(Personne, related_name='conversations')
messages = models.ManyToManyField(Message, related_name='conversations')
我已经personnes
一个ManyToManyField
(而不仅仅是src
和dst
)所以我可以拥有尽可能多的Person
会话。
我的问题是当我有这样的2个人时:
p_src = Personne.objects.get(user=self.request.user)
# i've got id_dst somewhere before
p_dst = Personne.objects.get(pk=id_dst)
我想找回“只有那两个人的对话”。
目前我正在做的是:
c = Conversation.objects.filter(
personnes__in=[p_src, p_dst]).distinct()
但结果看起来像是“那些 那两个人之间的对话”。
我该怎么办?
答案 0 :(得分:0)
这应该有效:
c = Conversation.objects.filter(personnes=p_src).filter(personnes=p_dst).distinct()
答案 1 :(得分:0)
您需要2个步骤才能实现此目的。首先,确保personnes
的数量等于您要匹配的Personne
数量。然后,您为每个Personne
实例过滤该字段:
from django.db.models import Count
personnes = [p_src, p_dst]
result = Conversation.objects.annotate(c=Count('personnes')).filter(c=len(personnes))
for personne in personnes:
result = result.filter(personnes=personne)
答案 2 :(得分:0)
这是一个工作解决方案,根本没有优化,所以如果你有任何其他更好的解决方案,我就是你的男人!
# filter all conversations where there are 2 participants and
# (1) src is part of them
convs_src = Conversation.objects.annotate(c=Count('personnes'))\
.filter(c=2)\
.filter(personnes__in=[p_src])
# (2) dst is part of them
convs_dst = Conversation.objects.annotate(c=Count('personnes'))\
.filter(c=2)\
.filter(personnes__in=[p_dst])
# ... then take the intersection, which should always be "one":
convs = set(list(convs_src)).intersection(list(convs_dst))
if len(convs): # get() = pour avoir un objet (!= QuerySet)
c = Conversation.objects.get(pk=convs[0])
else:
raise Exception('should never ever happen')
答案 3 :(得分:0)
我尝试找到p_src和p_dst在某个角色中的所有对话。
conversations_where_two_are_in = Conversations.objects.all().filter(
Q(personnes = p_src)|
Q(personnes = p_dst)
)
抛弃所有其他人参与这些对话的对话。除了这两个我们感兴趣的人之外,我找到所有人,并把它们放在一个清单中。
list_of_other_personnes = Personnes.objects.all().exclude(
personnes = p_src,
personnes = p_dst,
)
我将他们排除在我们两人所在的对话之外。
conversations_between_only_two = conversations_where_two_are_in.exclude(
personnes__in = list_of_other_personnes)
我希望它可以帮到你。请告诉我它不是。