Home > Enterprise >  Django - Is it possible to prefetch multiple filters of a single field for a queryset?
Django - Is it possible to prefetch multiple filters of a single field for a queryset?

Time:06-07

I know you can prefetch a single filtered queryset E.g.

Parent.objects.all()
.prefetch_related(
  Prefetch("child_set", queryset=Child.objects.filter(type="A")
)

That way running obj.child_set.all().count() will return the count of related A Childs without running another query.

But what if I wanted to have the B count too? So the following would take 2 queries - can I somehow prefetch them both?

return {
  "a_count": obj.log_set.filter(type="A").all().count(),
  "b_count": obj.log_set.filter(type="B").all().count(),
}

Edit: I've tried

Parent.objects.all()
.prefetch_related(
  Prefetch("child_set", queryset=Child.objects.filter(type="A"),
  Prefetch("child_set", queryset=Child.objects.filter(type="B")
)

But that gives me the following error when I try to access the object:

{
    "detail": "Not found."
}

CodePudding user response:

With regards to your main question, you can use Prefetch..[Django-doc] object on the same field with different filters, but assign them with different to_attr values like this:

from django.db.models import Prefetch


Parent.objects.prefetch_related(
    Prefetch(
        "child_set", 
        queryset=Child.objects.filter(type="A"), 
        to_attr="child_set_a"
    ),
    Prefetch(
        "child_set", 
        queryset=Child.objects.filter(type="B"), 
        to_attr="child_set_a"
    ),
)
  • Related