'How to join 2 tables in django ORM
I have 2 Tables. TableA and TableB.
id is the primary key in TableB and item_id is the foreign key in TableA.
My task is to find all the items from TableB where the id should match the item_ids.
I am able to get all the items with the below queries. But I'd like to understand how to apply joins on the both tables using select_related to get the same result.
item_ids = list(TableA.objects.filter(is_active=True).\
distinct().\
values_list('item_id', flat=True))
items = TableB.objects.filter(Q(id__in=item_ids) & \
Q(display_name__isnull=False) & \
Q(name__isnull=False)).\
values("name", "display_name")
model -->> TableA
class TableA(models.Model):
item = models.ForeignKey(TableB, on_delete=models.CASCADE
is_active = models.BooleanField(default=False)
class Meta:
unique_together = ('item',)
class TableB(models.Model):
name = models.SlugField(max_length=50, null=True, blank=True)
display_name = models.CharField(max_length=50)
is_active = models.BooleanField(default=False)
I'd like to translate below query into ORM
select DISTINCT TableB.name, TableB.display_name
from TableB
inner join TableA on TableA.item_id = TableB.id
where TableA.is_active=true AND
TableB.display_name is not NULL AND
TableB.name is not NULL
Could someone help me with the query?
Solution 1:[1]
You can use a related_name attribute in your item foreign key definition.
This way, you don't have to guess what the reverse relation is called from TableB.
item = models.ForeignKey(TableB, related_name='tablea', on_delete=models.CASCADE)
Then you can find your distinct values in a single query like this:
from django.db.models import Q
items = TableB.objects.filter(
Q(tablea__is_active=True) &
Q(display_name__isnull=False) &
Q(name__isnull=False)
).values(
'name', 'display_name'
).distinct(
'name', 'display_name'
).order_by(
'name', 'display_name'
)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
