select_related(*fields)
Returns a QuerySet
that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query. This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.
The following examples illustrate the difference between plain lookups and select_related()
lookups. Here’s standard lookup:
# Hits the database. e = Entry.objects.get(id=5) # Hits the database again to get the related Blog object. b = e.blog
And here’s select_related
lookup:
# Hits the database. e = Entry.objects.select_related('blog').get(id=5) # Doesn't hit the database, because e.blog has been prepopulated # in the previous query. b = e.blog
You can use select_related()
with any queryset of objects:
from django.utils import timezone # Find all the blogs with entries scheduled to be published in the future. blogs = set() for e in Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog'): # Without select_related(), this would make a database query for each # loop iteration in order to fetch the related blog for each entry. blogs.add(e.blog)
The order of filter()
and select_related()
chaining isn’t important. These querysets are equivalent:
Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog') Entry.objects.select_related('blog').filter(pub_date__gt=timezone.now())
You can follow foreign keys in a similar way to querying them. If you have the following models:
from django.db import models class City(models.Model): # ... pass class Person(models.Model): # ... hometown = models.ForeignKey( City, on_delete=models.SET_NULL, blank=True, null=True, ) class Book(models.Model): # ... author = models.ForeignKey(Person, on_delete=models.CASCADE)
... then a call to Book.objects.select_related('author__hometown').get(id=4)
will cache the related Person
and the related City
:
b = Book.objects.select_related('author__hometown').get(id=4) p = b.author # Doesn't hit the database. c = p.hometown # Doesn't hit the database. b = Book.objects.get(id=4) # No select_related() in this example. p = b.author # Hits the database. c = p.hometown # Hits the database.
You can refer to any ForeignKey
or OneToOneField
relation in the list of fields passed to select_related()
.
You can also refer to the reverse direction of a OneToOneField
in the list of fields passed to select_related
— that is, you can traverse a OneToOneField
back to the object on which the field is defined. Instead of specifying the field name, use the related_name
for the field on the related object.
There may be some situations where you wish to call select_related()
with a lot of related objects, or where you don’t know all of the relations. In these cases it is possible to call select_related()
with no arguments. This will follow all non-null foreign keys it can find - nullable foreign keys must be specified. This is not recommended in most cases as it is likely to make the underlying query more complex, and return more data, than is actually needed.
If you need to clear the list of related fields added by past calls of select_related
on a QuerySet
, you can pass None
as a parameter:
>>> without_relations = queryset.select_related(None)
Chaining select_related
calls works in a similar way to other methods - that is that select_related('foo', 'bar')
is equivalent to select_related('foo').select_related('bar')
.
Please login to continue.