Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to intersect two ManyToMany fields with a Django Query?

Tags:

join

django

Let's say I have the following Django models:

class A(models.Model):
    keywords = models.ManyToManyField(Keyword)

class B(models.Model):
    keywords = models.ManyToManyField(Keyword)

I have an A object. I want to find all B objects where some keyword in the B object is the same as some keyword in the A object.

What is the correct way to write this query?

like image 615
Joseph Turian Avatar asked Jan 18 '23 07:01

Joseph Turian


2 Answers

For my sanity, I'm replacing A and B with Article and Blog, respectively. It makes it a lot easier to parse the related names. So, we have:

class Article(models.Model):
    keywords = models.ManyToManyField(Keyword)

class Blog(models.Model):
    keywords = models.ManyToManyField(Keyword)

This should work, in one query:

article = Article.objects.all()[0]
Blog.objects.filter(keywords__in=Keyword.objects.filter(articles=article))

Django will combine the Keyword.objects.filter into the Blog.objects.filter query, making just one database call.

like image 186
Jordan Reiter Avatar answered Jan 20 '23 19:01

Jordan Reiter


If a is an instance of A, something like that should do:

B.objects.filter(keywords__pk__in=a.keywords.values_list('pk', flat=True))
like image 27
Bernhard Vallant Avatar answered Jan 20 '23 20:01

Bernhard Vallant