django - 如何在多对多字段中查询所描述的对象的位置

时间:2013-12-03 21:55:02

标签: django django-models django-views django-orm

如何检查是否thread仅包含sender(用户1)和recipient(用户2),而不包含其他用户。

models.py

class Thread(models.Model):
    user = models.ManyToManyField(User)
    is_hidden = models.ManyToManyField(User, related_name='hidden_thread', blank=True)

class Message(models.Model):
    thread = models.ForeignKey(Thread)
    sent_date = models.DateTimeField(default=datetime.now)
    sender = models.ForeignKey(User)
    body = models.TextField()
    is_hidden = models.ManyToManyField(User, related_name='hidden_message', blank=True)

我试过

>>> Thread.objects.filter(user=user1&user2)
>>> Thread.objects.filter(user=user1|user2)
# Both gave me an error:  Unsupported operand.

# Then this
>>> Thread.objects.filter(Q(user=user1) & Q(user=user2))
# Which gave me no threads at all.

# Then this
>>> Thread.objects.filter(Q(user=user1) | Q(user=user2)).distinct()
# Gave me threads of both the users.

我想要的是仅检查指定用户的线程。假设,用户1想要向用户2发送消息。我想要的是,首先检查两个用户之间是否有线程。如果有,获取该线程,或者创建一个新线程。这怎么可能?什么是最好的方法。请帮我。谢谢。

请告诉我|&之间有什么区别?因为这两个人的结果差异很大。

修改

>>> t1 = Thread.objects.get(id=1)
>>> t1
[<User: a>,<User: b>]
>>> t2 = Thread.objects.get(id=2)
>>> t2
[<User: a>,<User: b>,<User: c>]
>>> t3 = Thread.objects.get(id=3)
>>> t3
[<User:a>,<User: c>]
>>> t4 = Thread.objects.get(id=4)
>>> t4
[<User:a>,<User:b>]

我想要的是获取仅存在用户a和用户b的线程,而不存在其他用户。在这种情况下,它将是:t1t4。希望我清楚自己。谢谢。

2 个答案:

答案 0 :(得分:4)

excludedUsers = Users.objects.exclude(id__in=[user1.id, user2.id])
Thread.objects.filter(users=user1).filter(users=user2).exclude(users__in=excludedUsers)

答案 1 :(得分:1)

  

假设,用户1想要向用户2发送消息。我想要的是,   首先检查两个用户之间是否有线程。

请记住,过滤器会返回一个列表,所以如果有多个 相同用户之间的线程,你会得到多个结果。

如果您使用的是postgresql,则可以使用此语法,该语法仅返回不同的线程(消除重复的线程):

threads = Message.objects.filter(sender=user1) \
                         .filter(thread__user=user2)
                         .distinct('thread')

如果没有,那么您需要自己过滤掉重复项:

thread_ids = set(Message.objects.filter(sender=user1) \
                         .filter(thread__user=user2)
                         .values_list('thread__pk', flat=True))
threads = list(Thread.objects.get(pk=i) for i in thread_ids)

if not threads:
    # create a new thread
else:
    # Choose from one of the existing threads

现在您拥有这两个用户的唯一线程;你需要消除所有那些拥有其他人的线程:

threads.filter(user__in=[user1, user2])