Django

django | select_related()

JOOHUUN 2022. 8. 14. 13:57

구하려는 객체가 역참조하는 single object(one-to-one or many-to-one)이거나, 또는 정참조 foreign key 일 때 사용한다.

class City(models.Model):
    name = models.CharField(max_length=200)
    
    def __str__(self):
        return self.name

class Person(models.Model):
    # ...
    hometown = models.ForeignKey(
        City,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    
    def __str__(self):
        return self.hometown.name

class Book(models.Model):
    # ...
    author = models.ForeignKey(Person, on_delete=models.CASCADE)
    
    def __str__(self):
        return self.author.hometown.name

 

1. 일반적인 조희

In [2]: Book.objects.get(id=2)
Out[2]: <Book: 책2>

In [3]: Book.objects.get(id=2).author
Out[3]: <Person: 테스트2>

2. select_related 조회

In [4]: Book.objects.select_related('author').get(id=2)
Out[4]: <Book: 책2>

In [5]: Book.objects.select_related('author').get(id=2).author
Out[5]: <Person: 테스트2>

3. select_related와 filter의 순서는 상관 없다.

In [9]: Book.objects.select_related('author').filter(id=3)
Out[9]: <QuerySet [<Book: 책3>]>

In [11]: Book.objects.filter(id=3).select_related('author')
Out[11]: <QuerySet [<Book: 책3>]>

4. 불필요한 호출을 줄인다.

# select_realted 사용 할 경우
In [12]: b = Book.objects.select_related('author__hometown').get(id=1)
In [13]: p = b.author			# Doesn't hit the database.
In [14]: c = p.hometown			# Doesn't hit the database.

# select_realted 사용 하지 않는 경우
In [15]: b = Book.objects.get(id=4)			# Hits the database.
In [16]: p = b.author					# Hits the database.
In [17]: c = p.hometown					# Hits the database.