> ## Content Index
> Fetch the complete content index at: https://multitasked.net/llms.txt
> Use this file to discover other available public pages before exploring further.

# Inner join query with distinct using Django ORM
- URL: https://multitasked.net/2010/07/08/082300/
- Published: 2010-07-08T06:23:00.000Z
- Updated: 2026-09-04T10:08:37.000Z
- Author: Martin De Wulf

One point of the Django documentation that I did not get right at first is : how to get the ORM to generate a bit complex join queries. Yeah, sorry, I learnt SQL before ORMs, as many people, and I definitely think in terms of relational models and SQL joins.

For example, given the following models involving deliveries of products in a driver schedule, how do you get the list of products appearing in a schedule ? (I know that this sounds a lot like a Data Base 101 course).

class Product(models.Model):  
name = models.CharField(max\_length=150)  
class Schedule(models.Model):  
name = models.CharField(max\_length=150)  
class Delivery(models.Model):  
.... some data fields here  
product=models.ForeignKey(Product)  
schedule=models.ForeignKey(Schedule)  

The answer is deceptively simple, just write :

s = Schedule.objects.get(....)  
Product.objects.filter(delivery\_\_schedule = s).distinct()  

which roughly will translate into the following SQL :

select distinct(product.\*) from product  
inner join delivery on product.id = delivery.product\_id  
inner join schedule on schedule.id = delivery.schedule\_id  
where schedule.id = some\_id  

The important thing to notice is that in the line

Product.objects.filter(delivery\_\_schedule = s).distinct()  

you can use **delivery** as the beginning of the lookup parameters, while there is no **delivery** field in the **Product** class. Django will understand.

What is maybe a bit misleading (even if it is quite logical if you think about it), is that there actually is a field named **delivery\_set** created on the Product class (it is a [RelatedManager](http://docs.djangoproject.com/en/dev/topics/db/queries/?ref=multitasked.net#related-objects)), but you can not use it in the lookup parameters. It took me a long time to figure this out, so it might be the case for other people too....

That said, everything is explained in the Django doc [here](http://docs.djangoproject.com/en/1.2/topics/db/queries/?ref=multitasked.net#lookups-that-span-relationships) even if for once, I find the explanation a bit perfunctory