For example, I have these models:
class Person(models.Model):
name = models.CharField(max_length=20)
employer = models.CharField(max_length=20)
class Car(models.Model):
person = models.ForeignKey(Person)
name = models.CharField(max_length=10)
model = models.CharField(max_length=10)
...
I want to get all people who own some specific car:
people = Person.objects.filter(car__name="Toyota")
Now I want to write these people out with details about their own car. I can do this:
for person in people:
...
cars = person.car_set.filter(name="Toyota")
...
But it hit the database again. How can I avoid this? Is there any way to do this simpler?
First select the car and the related person when the car name
cars = Car.objects.select_related("person").filter(name="Toyota").order_by("person")
Now you have all the cars whose name is toyota along with the person for that car, ordered_by person.
Now use the python itertools.groupby to group this list for each person
from itertools import groupby
for k, g in groupby(cars, lambda x: x.person):
person = k
cars = list(g)
Now in that iteration you have the person and his cars (whose name is "toyota"). You'll notice that there is only single query that occurs, and then the following operations execute on the cached information.