When the object that you're going to be selecting is a single object, so OneToOneField or a ForeignKey.
Below is an example for select_related
!!
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=300)
def __str__(self):
return self.name
class Book(models.Model):
name = models.CharField(max_length=300)
price = models.IntegerField(default=0)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
class Meta:
default_related_name = 'books'
def __str__(self):
return self.name
book_list_select_related.py
shows the example of select_related and let's see what happens.
def book_list_select_related():
queryset = Book.objects.select_related('publisher').all()
books = []
for book in queryset:
books.append({'id': book.id, 'name': book.name, 'publisher': book.publisher.name})
return books
After running this function, the output shows:
Function : book_list_select_related
Number of Queries : 1
Finished in : 0.02s
When you're going to get a "set" of things, so ManyToManyFields as you stated or reverse ForeignKeys.
Just to make sure with an example!!!
class ModelA(models.Model):
pass
class ModelB(models.Model):
a = ForeignKey(ModelA)
ModelB.objects.select_related('a').all() # Forward ForeignKey relationship
ModelA.objects.prefetch_related('modelb_set').all() # Reverse ForeignKey relationship
The difference is that select_related
does an SQL join and therefore gets the results back as part of the table from the SQL server. prefetch_related
on the other hand executes another query and therefore reduces the redundant columns in the original object (ModelA in the above example). '
You may use prefetch_related for anything that you can use select_related for.
Below is models.py
file for prefetch_related
example!!
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=300)
def __str__(self):
return self.name
class Book(models.Model):
name = models.CharField(max_length=300)
price = models.IntegerField(default=0)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
class Meta:
default_related_name = 'books'
def __str__(self):
return self.name
class Store(models.Model):
name = models.CharField(max_length=300)
books = models.ManyToManyField(Book)
class Meta:
default_related_name = 'stores'
def __str__(self):
return self.name
store_list_prefetch_related.py
shows prefetch_related
example and let's see what happens.
def store_list_prefetch_related():
queryset = Store.objects.prefetch_related('books')
stores = []
for store in queryset:
books = [book.name for book in store.books.all()]
stores.append({'id': store.id, 'name': store.name, 'books': books})
return stores
After running this function, the output shows:
Function : store_list_prefetch_related
Number of Queries : 2
Finished in : 0.01s