Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Q objects and the '&' operator in django

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?

like image 809
DantheMan Avatar asked Dec 24 '10 00:12

DantheMan


People also ask

What are Q objects Django?

Q object encapsulates a SQL expression in a Python object that can be used in database-related operations. Using Q objects we can make complex queries with less and simple code. For example, this statement returns if the question starts with 'who' or with 'what'.

Why are QuerySets considered lazy?

This is because a Django QuerySet is a lazy object. It contains all of the information it needs to populate itself from the database, but will not actually do so until the information is needed.


1 Answers

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.

like image 124
Ignacio Vazquez-Abrams Avatar answered Oct 09 '22 10:10

Ignacio Vazquez-Abrams