I have a pk list of instances of Tag model, say
pk_list = [10, 6, 3]
I have another model with m2m field of tags and an instance that contains exactly 3 tags (of above pks).
class Node(models.Model):
...
tags = models.ManyToManyField(Tag, related_name='nodes')
I'd like to retrieve a Node that contains exact set of tags as specified in my pk_list. When I do
Node.objects.filter(tags__in=pk_list)
it returns a list of three same instances
[<Node: My node title>, <Node: My node title>, <Node: My node title>]
Calling .get() doesn't work cause it have to return a single instance, obviously.
So, how do I retrieve a single instance? I must note that if my pk_list was different eg. [10, 6] or [10, 6, 3, 7] then I must receive nothing. I need an exact matching.
Thanks
One approach is to use chain of filters:
node_query = Node.objects.all()
pk_list = [10, 6, 3]
for pk in pk_list:
node_query = node_query.filter(tags=pk)
Now node_query will match node, that has at least three tags with pk 10, 6, 3. To exact matching of three tags:
UPDATE: Thanks to @janos and @Adrián López, the correct answer is:
from django.db.models import Count
pk_list = [10, 6, 3]
node_query = Node.objects.annotate(count=Count('tags')).filter(count=len(pk_list))
for pk in pk_list:
node_query = node_query.filter(tags__pk=pk)
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