select_related() and prefetch_related() both fix the N+1 problem, but they work differently. Here's the practical difference.
The rule
select_related β SQL JOIN, one query. For ForeignKey and OneToOne.
prefetch_related β separate queries, joined in Python. For ManyToMany and reverse ForeignKey.
Example models
class Book ( models . Model ) : title = models . CharField ( max_length = 200 ) author = models . ForeignKey ( Author , on_delete = models . CASCADE , related_name = "books" ) publisher = models . ForeignKey ( Publisher , on_delete = models . CASCADE ) tags = models . ManyToManyField ( Tag , related_name = "books" )
class Review ( models . Model ) : book = models . ForeignKey ( Book , on_delete = models . CASCADE , related_name = "reviews" ) rating = models . PositiveSmallIntegerField ( ) approved = models . BooleanField ( default = False )
Enter fullscreen mode
Exit fullscreen mode
Before: 201 queries
for book in Book . objects . all ( ) [ : 100 ] : print ( book . title , book . author .β¦