1

I'm querying a ManyToMany field (tags). The values come from a list:

tag_q = Q()

tag_list = ["work", "friends"]
for tag in tag_list:
    tag_q &= Q(tags__tag=tag)

Post.objects.filter(tag_q)

When I have only one value, it works flawlessly, but when more objects are stacked it always return an empty queryset.

I didn't used tags__tag__in=tag_list because it returned any post that contained any of the tags in the tag list (an OR filter), and I need an AND filter here.

This is my models:

class Tag(models.Model):
    tag = models.CharField(max_length=19, choices=TagChoices.choices())

class Post(models.Model):
    tags = models.ManyToManyField(Tag, related_name='posts', blank=True)

This is the Q object that is being passed in the filter query:

(AND: ('tags__tag', 'work'), ('tags__tag', 'friends')
1
  • 1
    You can not work with a Q object like that: a filter is an existential quantifier, not a universal. It means you are looking for a single Tag that has as tag name work and friends at the same time. Commented Oct 29, 2021 at 10:27

1 Answer 1

1

You can not work with a Q object like that: a filter is an existential quantifier, not a universal. It means you are looking for a single Tag that has as tag name work and friends at the same time.

What you can do is work with a list of tags, and then count if the number of Tags is the same as the number of items to search for, like:

tag_list = ['work', 'friends']

Post.objects.filter(tags__tag__in=tag_list).annotate(
    ntags=Count('tags')
).filter(ntags=len(set(tag_list))

since , you can work with .alias(…) [Django-doc] instead of .annotate(…) [Django-doc]:

tag_list = ['work', 'friends']

Post.objects.filter(tags__tag__in=tag_list).alias(
    ntags=Count('tags')
).filter(ntags=len(set(tag_list))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.