Lets say tat I have such a model:
class Conversation(models.Model):
sid = models.CharField(
max_length=34,
primary_key=True
)
members = models.ManyToManyField(to=User)
I would like to find a Conversation that is connected exactly/only with users [1,2]
I tried this:
conversation = Conversation.objects.filter(
members__in=[1, 2]
)
But it returns all conversation that are connected with either user 1, or 2.
I tried this: other answer but It returns empty queryset.
We can count how many members
match the list, and check if that includes all the members
:
from django.db.models import Count, Q
members = [1,2]
members_len = len(set(members))
Conversation.objects.annotate(
total_members=Count('members'),
matching_members=Count('members', filter=Q(members__in=members))
).filter(
matching_members=members_len,
total_members=members_len
)
This thus will retrieve Converstion
s that contain all members in the members
list, and only these members (so not a superset, nor a subset).
Or for pre django-2.0 installations:
from django.db.models import Case, Count, When
members = [1,2]
members_len = len(set(members))
Conversation.objects.annotate(
total_members=Count('members'),
matching_members=Count(Case(
When(members__in=members, then='members'),
default=None
))
).filter(
matching_members=members_len,
total_members=members_len
)
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