I have these two classes for a messaging module I'm working on. The idea is that a conversation is represented by a group of participants (two or more). I'm struggling to find a way to look up a conversation by the logic saying that the desired conversation I'm trying to find has the following participants. I tried Conversation.objects.filter(participants__in=[p1, p2])
however this does an OR style query, p1 is a participant or p2 is a participant. I want p1 and p2 and... pN is a participant. Any help out there?
class Conversation(models.Model):
date_started = models.DateTimeField(auto_now_add=True)
participants = models.ManyToManyField(User)
def get_messages(self):
return Message.objects.filter(conversation=self)
def new_message(self, sender, body):
Message.objects.create(sender=sender, body=body, conversation=self)
self.save()
class Message(models.Model):
sender = models.ForeignKey(User)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
conversation = models.ForeignKey(Conversation)
def __unicodde__(self):
return body + "-" + sender
I think you just need to iteratively filter. This could be utter nonsense as I'm a bit sleep deprived, but maybe a manager method like so:
class ConversationManager(models.Manager):
def has_all(self, participants):
# Start with all conversations
reducedQs = self.get_query_set()
for p in participants:
# Reduce to conversations that have a participant "p"
reducedQs = reducedQs.filter(participants__id=p.id)
return reducedQs
Generally speaking, you should get in the habit of making table-level queries manager methods, as opposed to class methods. And by doing it this way, you're left with a queryset that you can filter further if need be.
Inspired by the query of all Groups that have a member name Paul in the documentation and this answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With