Django M2M QuerySet filtering on multiple foreign keys
django, django-queryset, many-to-many, python
Solution
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.
Problem
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 ```