Assuming these as django model for the sake of simplcity:
class A(): a = manytomany('B') class B(): b = charfield() z = foreignkey('C') class C(): c = charfield()
Can we do something like this to fetch the z
also:
foo = A.objects.get(pk = 1).prefetch_related('a').select_related('a__z')
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.
We use select_related when the object that you're going to select is a single object, which means forward ForeignKey, OneToOne and backward OneToOne . select_related works by creating an SQL join and including the fields of the related object in the SELECT statement.
A QuerySet is a collection of data from a database. A QuerySet is built up as a list of objects. QuerySets makes it easier to get the data you actually need, by allowing you to filter and order the data.
This answer is correct with versions of Django prior to 1.7. It produces three queries: first, fetch the instance of A
, then fetch its related instances of B
and finally fetch the instances of C
related to those of B
fetched in the second query.
Before Django 1.7, this is the best you can do, even though the second query could, in theory, select all B
objects together with the related C
objects joined through the z
ForeignKey
.
Starting with Django 1.7, there's a more advanced django.db.models.Prefetch
class which allows you to do just that. With Prefetch
you can customize the queryset used to prefetch related objects like this:
foo = A.objects.prefetch_related( Prefetch('a', queryset=B.objects.select_related('z')) ).get(pk=1)
This results in only two queries (as opposed to three when using prefetch_related('a__z')
) and lets the database take care of the second join, which should in theory result in slightly better performance.
You only need one prefetch_related
call:
foo = A.objects.prefetch_related('a__z').get(pk=1)
This will prefetch both tables. In Django 1.7+ you can improve performance by using a Prefetch
object, as in koniiiik's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With