Q objects and the '&' operator in django

DantheMan picture DantheMan · Dec 24, 2010 · Viewed 9.2k times · Source

I have a curious problem.

I have 3 objects. All the same

class Articles(models.Model):
    owner = models.ForeignKey(Author)
    tags = models.ManyToManyField('Tag')


class Tag(models.Model):
     name = models.CharField(max_length=255)

and so I have 3 Articles. With all the same tags: 'tag1' and 'tag2'

And I have queries

actionsAll = Articles.objects.filter((Q(tags__name__exact="tag1") | Q(tags__name__exact="tag2"))).distinct()

This gives me all my articles. It will return 6 articles w/o distinct() since it will collect each article 2x since they have both tags.

However with this query:

actionsAll = Articles.objects.filter((Q(tags__name__exact="tag1") & Q(tags__name__exact="tag2"))).distinct()

This gives me no articles. Since the articles contain both the tags, it should return them all shouldnt it?

Answer

Ignacio Vazquez-Abrams picture Ignacio Vazquez-Abrams · Dec 24, 2010

If you look at the SQL it generates, you'll see that it checks to see if the same tag has both names. What you need is an IN query or an EXISTS query that traverses the relation.