My model:
class Foo(models.Model):
name = models.CharField(unique=True, max_length=50)
self_foo = models.ForeignKey(to="self", on_delete=models.PROTECT)
class Bar(models.Model):
name = models.CharField(unique=True, max_length=30 )
parent_foo = models.ForeignKey(to=Foo, on_delete=models.PROTECT)
Lets do some inspections:
>>> from polls.models import Foo, Bar
>>> print(Bar.objects.all().query)
SELECT "polls_bar"."id", "polls_bar"."name", "polls_bar"."parent_foo_id" FROM "polls_bar"
This looks as expected.
However:
>>> print(Bar.objects.select_related().query)
SELECT "polls_bar"."id", "polls_bar"."name", "polls_bar"."parent_foo_id", "polls_foo"."id", "polls_foo"."name", "polls_foo"."self_foo_id", T3."id", T3."name", T3."self_foo_id", T4."id", T4."name", T4."self_foo_id", T5."id", T5."name", T5."self_foo_id", T6."id", T6."name", T6."self_foo_id" FROM "polls_bar"
INNER JOIN "polls_foo" ON ("polls_bar"."parent_foo_id" = "polls_foo"."id")
INNER JOIN "polls_foo" T3 ON ("polls_foo"."self_foo_id" = T3."id")
INNER JOIN "polls_foo" T4 ON (T3."self_foo_id" = T4."id")
INNER JOIN "polls_foo" T5 ON (T4."self_foo_id" = T5."id")
INNER JOIN "polls_foo" T6 ON (T5."self_foo_id" = T6."id")
Why there is four extra tables joined in my query? How can I control that? I’d like only one extra join.
I’ve found the magic setting max_depth=5
in django.db.models.sql.query
, but this seems very internal. I now that I can do Bar.objects.select_related("parent_foo")
to stop this behaviuor, however then I have to specify all other foreing keys I want to include as related in my query.
In reality my model is much bigger, and I want to use build in ModelAdmin, and I really don’t want to go through maintaing select_related setting in all of my models just to list all FK’s there. Without this, I am very quickly hitting limits such as jango.db.utils.OperationalError: at most 64 tables in a join
or too many columns in result set
.