Django prefetch related by int PK?

I have a model "A" that has:

class A:
  my_fk = models.IntegerField(...)

Then doing a query like this:

queryset = A.prefetch_queryset().prefetch_related("somemodel")

that all works.

Now I want to prefetch from table B where B.id = A.my_fk. my_fk isn't a model itself, just the int foreign key to one.

Is that possible? Don't want to change the type of my_fk though...

From what I understand you seek a method doing a prefetch on B using integers (that function as foreign keys) stored in A. But as far as I know even a Prefetch object that would allow to do something like:

from django.db.models import Prefetch

result = C.objects.all().prefetch_related(
    Prefetch(
        "b_set",
        queryset=B.objects.filter(pk__in= ... do some subquery with A),
        to_attr="bees_and_ayes"
    )
)

does not work since Prefetch needs a reverse set (b_set here). We assume there is model C for which you want to do the prefetching on B using keys from A but you have no relation.

What you could do instead is to create a new relation using annotate() (See documentation) combined with a SubQuery (See more documentation). Without developing proper working code a solution could look alike:

from django.db.models import OuterRef, Subquery

B.objects.annotate(
    a_artificial_set=Subquery(
        A.objects.filter(my_fk=OuterRef('id'))
    )
)

As django allows nested subqueries, you should be able to put this into another query C.objects.annotate() with another SubQuery using an OuterRef from C such that the above query acts as your final prefetch.

Back to Top