Assume the following models
Class A(): pass
Class B():
i = integer()
aa = foreignkey('A', related_name = 'fka')
For simplicity assume the below entries,
A() - a1 -> pk = 1
B() - b1 -> i = 1, aa = a1
B() - b2 -> i = 2, aa = a1
B() - b3 -> i = 3, aa = a1
B() - b4 -> i = 4, aa = a1
B() - b5 -> i = 5, aa = a1
I know,
foo = A.objects.get(pk = 1).prefetch_related('fka')
will give me the entries b1, b2, b3, b4 and b5.
But what I want to know is, is it possible to alter this query in anyway to get only a particular entry of B() associated with A(). Suppose I want to prefetch only entry of 'B', with 'i' as 2 (get b2, and skip b1, b3, b4 and b5).
If it is not possible to do it using the prefetch then, what is the best way to do it ?
Note: get(pk = 1) is used to keep the simplicity for explanation, but at that place usually there will be filter(**conditions).
Is it necessary to do the query on the A objects rather than the B objects? If you reverse what you do the additional lookup on, you could use select_related():
foo = B.objects.select_related('aa').get(i=2)
This has the advantage of reducing your number of database hits. Because prefetch_related() always does its own database lookup, your proposed scenario of using prefetch_related() isn't any more efficient, as written, than simply doing:
a = A.objects.get(pk=1)
b = a.fka.get(i=2)
That's not to say it wouldn't be more efficient in scenarios with more complex filtering, but select_related() uses a SQL join and therefore only hits the database once. That said, if you absolutely must lookup the A objects first, the best answer would be: upgrade to Django 1.7. The new Prefetch command in Django 1.7 allows for more complex operations on prefetch_related(), including filtering, by allowing you to specify custom querysets:
qs = B.objects.filter(i=2)
foo = A.objects.get(pk = 1).prefetch_related(Prefetch('fka',qs))
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