Select_related & Prefetch_related

77raina·2020년 5월 31일
0

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!!!

Reverse ForeignKeys

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
profile
Backend Developer

0개의 댓글