Thank you so much! That was a very helpful explanation. And it worked perfectly!!!
Just, one more question please. Suppose, the user wants to send a message to a group of users, how do I find the thread in this situation? Eg: user1 wants to send a message to both the user2 and user3. How to find the thread, in this case '*t3*'? >>> t1 = Thread.objects.get(id=1) >>> t1 [<User: user1>,<User: user3>] >>> t2 = Thread.objects.get(id=2) >>> t2 [<User: user1>,<User: user2>] >>> t3 = Thread.objects.get(id=3) >>> t3 [<User: user1>,<User: user2>,<User: user3>] On Wed, Dec 4, 2013 at 5:41 PM, Tom Evans <tevans...@googlemail.com> wrote: > On Wed, Dec 4, 2013 at 10:24 AM, Aamu Padi <aamup...@gmail.com> wrote: > > How do I check whether there is a thread containing only the sender > (user 1) > > and the recipient (user 2), and no other users. > > > > 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) > > > > I tried > > > > >>> 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. > > > > What I want is to check the thread, with the specified users only. > Suppose, > > User 1 wants to send a message to User 2. What I want is, first check > > whether there is a thread between both the users. If there is, get that > > thread, or else create a new one. How is it possible? What is the best > way > > to do it. Please help me. Thank you. > > I hope you understand SQL a little, as it will be required to follow > this explanation. > > The condition "Thread.objects.filter(user=..)" goes across a join to > the users<->threads "through" table, which has columns (id, thread_id, > user_id). > > When you specify conditions in a "filter()" call, each of the > conditions specified in that call is AND'ed together (the equivalent > of what you were doing in the "Q(user=user1) & Q(user=user2)", django > would do that for you). However, what does that mean, in terms of SQL? > > Well, it means "find me rows from the users<->threads through table > that have user_id=user1.pk and user_id=user2.pk". Obviously, this will > never find results unless user1==user2. > > So, you need to specify that you want to join twice to that table. You > do this by specifying the conditions for each join in a separate > "filter()" call, and so to find threads that have a row with user1 in > the through table, and also have user2 in the through table: > > Thread.objects.filter(user=user1).filter(user=user2) > > You started by asking how to find threads which had user1 and user2, > but no other users. This is more complex, you need to count the number > of users in the thread without filtering the users first! This means > two queries, or a sub query: > > threads_with_both = Thread.objects.filter(user=user1).filter(user=user2) > threads_with_only_both = Thread.objects.filter( > pk__in=threads_with_both).annotate( > num_users=Count('user')).filter( > num_users=2) > > > > > And please tell me what's the difference between | and &? Because I had > very > > different results with these two. > > | is OR > & is AND > > So to find threads with either user1 or user2 (or both): > > Thread.objects.filter(Q(user=user1) | Q(user=user2)) > > To find hidden threads with user1 > > Thread.objects.filter(Q(user=user1) & Q(is_hidden=True)) > > which is the same as > > Thread.objects.filter(user=user1, is_hidden=True) > > > Cheers > > Tom > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users+unsubscr...@googlegroups.com. > To post to this group, send email to django-users@googlegroups.com. > Visit this group at http://groups.google.com/group/django-users. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/CAFHbX1J%3DWX9p12B2X%2B1b_afDF0yEr80t0cfBsGbggzrKEBqqTg%40mail.gmail.com > . > For more options, visit https://groups.google.com/groups/opt_out. > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at http://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAHSNPWtFyCQupfcVdGgJVnpKBUh62R7%3DA2VBnSZzqbZnoATtKQ%40mail.gmail.com. For more options, visit https://groups.google.com/groups/opt_out.