Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Optimize queries with select_related()

I have the following model.

class Car(models.Model):
    owner = models.ForeignKey('Driver')

class Country(models.Model)
    name = models.CharField(max_length=255)

class Driver(models.Model):
    name = models.CharField(max_length=255)
    age = models.IntegerField()
    country = models.ForeignKey('Country')

I want to select the name of drivers owning a car.

Car.objects.all().values('owner__name')

Do I need to use select_related() method, to avoid a join for each object, or it is redundant because implicit with values() method?

Car.objects.all().select_related('owner').values('owner__name')

In the same way, I want, this time, the name of countries with drivers owning a car. Which one is the best?

Car.objects.all().values('owner__country__name')
Car.objects.all().select_related('owner', 'country').values('owner__country__name')
Car.objects.all().select_related('owner__country').values('owner__country__name')
like image 476
srjjio Avatar asked Nov 22 '25 08:11

srjjio


1 Answers

First, all the occurrences of .all() in your examples can be deleted; the manager (.objects) already has almost all methods of the QuerySet, except for .delete().

.select_related is only helpful when your eventual query returns model instances; then, all the foreign key of each instance will be pre-loaded.

But if you are using .values you are getting dictionaries, and there are no foreign key attributes to pre-load. So it should not be used in that case.

When you do .values('owner__name') Django already sees that it needs to join owners and cars, no extra queries are done.

In the last one you want Countries, so use Country.objects:

Country.objects.filter(driver__car__isnull=False).values('name')
like image 186
RemcoGerlich Avatar answered Nov 24 '25 22:11

RemcoGerlich



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!