class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
p1 = Publication.objects.create(title='The Python Journal')
p2 = Publication.objects.create(title='Science News')
p3 = Publication.objects.create(title='Science Weekly')
I want to filter articles, published in both p1
and p3
. They might or might not publish in other publications but they must have to publish in p1
and p3
.
I have tried:
Article.objects.filter(Q(publications=p1) & Q(publications=p3))
but it returns empty queryset which is not true
CodePudding user response:
If you chain mutliple calls to filter()
they should behave like being connected with an AND
:
articles = Article.objects.filter(publications=p1).filter(publications=p3).distinct()
CodePudding user response:
There are many examples of FOO__in=...
style filters in the many-to-many and many-to-one tests. Here is syntax for your specific problem:
# filtering on a few publications, by id
articles = Article.objects.filter(publications__in=[<id1>, <id2>, <id3>])
# and by publication object (object gets converted to pk under the covers)
articles = Article.objects.filter(publications__in=[publication1, publication2, publication3])
# and by publication title
articles = Article.objects.filter(publications__title__icontains='Science')
The icontains
used to i
for case-insensitive, contains
for that the word contains those letters and maybe there are fewer or more letters.
The double underscore (__) syntax is used all over the place when working with queryset.