gmcc051
gmcc051

Reputation: 410

Using django select_related with an additional filter

I'm trying to find an optimal way to execute a query, but got myself confused with the prefetch_related and select_related use cases.

I have a 3 table foreign key relationship: A -> has 1-many B h-> as 1-many C.

class A(models.model):
   ...

class B(models.model):
   a = models.ForeignKey(A)

class C(models.model):
   b = models.ForeignKey(B)
   data = models.TextField(max_length=50)

I'm trying to get a list of all C.data for all instances of A that match a criteria (an instance of A and all its children), so I have something like this:

qs1 = A.objects.all().filter(Q(id=12345)|Q(parent_id=12345))
qs2 = C.objects.select_related('B__A').filter(B__A__in=qs1)

But I'm wary of the (Prefetch docs stating that:

any subsequent chained methods which imply a different database query will ignore previously cached results, and retrieve data using a fresh database query

I don't know if that applies here (because I'm using select_related), but reading it makes it seem as if anything gained from doing select_related is lost as soon as I do the filter.

Is my two-part query as optimal as it can be? I don't think I need prefetch as far as I'm aware, although I noticed I can swap out select_related with prefetch_related and get the same result.

Upvotes: 1

Views: 1763

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599600

I think your question is driven by a misconception. select_related (and prefetch_related) are an optimisation, specifically for returning values in related models along with the original query. They are never required.

What's more, neither has any impact at all on filter. Django will automatically do the relevant joins and subqueries in order to make your query, whether or not you use select_related.

Upvotes: 2

Related Questions