Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Does prefetch_related() follow reverse relationship lookup?

I've tried prefetch_related() in django 1.4 from trunk and can't make it to prefetch reverse lookup.

My simplified models (each book has many prices):

class Book(models.Model):     # some fields  class Price(models.Model):     book = models.ForeignKey(Book) 

My view's query:

books = Book.objects.prefetch_related('price') 

Then, I got the AttributeError message:

AttributeError: Cannot find 'price' on Book object, 'price' is an invalid parameter to prefetch_related() 

How to make it work? Thanks.

like image 343
Tianissimo Avatar asked Feb 07 '12 12:02

Tianissimo


People also ask

What does Prefetch_related do in Django?

In Django, select_related and prefetch_related are designed to stop the deluge of database queries that are caused by accessing related objects. In this article, we will see how it reduces the number of queries and make the program much faster.

What's the difference between select_ related and prefetch_ related?

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).

How select_ related works?

select_related works by creating an SQL join and including the fields of the related object in the SELECT statement. For this reason, select_related gets the related objects in the same database query.

What is reverse relation in Django?

Thats' where related name or the reverse relationship comes in. Django, by defaults gives you a default related_name which is the ModelName (in lowercase) followed by _set - In this case, It would be profile_set , so group. profile_set . However, you can override it by specifying a related_name in the ForeignKey field.


1 Answers

Define a related name:

class Price(models.Model):     book = models.ForeignKey(Book, related_name='prices') 

and then use it:

books = Book.objects.prefetch_related('prices') 
like image 186
Jan Pöschko Avatar answered Sep 22 '22 08:09

Jan Pöschko