I’ve got a Django view that I’m trying to optimise. It shows a list of parent objects on a page, along with their children. The child model has the foreign key back to the parent, so select_related doesn’t seem to apply.
class Parent(models.Model):
name = models.CharField(max_length=31)
class Child(models.Model):
name = models.CharField(max_length=31)
parent = models.ForeignKey(Parent)
A naive implementation uses n+1 queries, where n is the number of parent objects, ie. one query to fetch the parent list, then one query to fetch the children of each parent.
I’ve written a view that does the job in two queries – one to fetch the parent objects, another to fetch the related children, then some Python (that I’m far too embarrassed to post here) to put it all back together again.
Once I found myself importing the standard library’s collections module I realised that I was probably doing it wrong. There is probably a much easier way, but I lack the Django experience to find it. Any pointers would be much appreciated!
Add a
related_nameto the foreign key, then use theprefetch_relatedmethod which added to Django 1.4:All the relevant children will be fetched in a single query, and used
to make QuerySets that have a pre-filled cache of the relevant
results. These QuerySets are then used in the
self.children.all()calls.