Semantics when calling select_related repeatedly

75 views
Skip to first unread message

Jeremy Dunck

unread,
Sep 20, 2011, 12:29:53 PM9/20/11
to django-d...@googlegroups.com
Currently, calling select_related causes the QS to forget previously
added fields. Also, it seems that depth calls are not forgotten.

For example, cribbing from the tests here:
https://code.djangoproject.com/browser/django/trunk/tests/modeltests/select_related/tests.py#L129

If this:
Species.objects.select_related('genus__family')
were replaced with
Species.objects.select_related('genus__family').select_related('genus')
then the query count would go up.

That may be intuitive when written all at once, but consider when
'genus__family' is set by a default manager, and later some queryset
is constructed with select_related('genus').

Additionally, if it were:
Species.objects.select_related(depth=1).select_related('genus__family')
I'm not sure what should happen.

It seems to me that calling .select_related should be additive, and if
you didn't want a previously select_related in effect, you should have
a way to reset it. The .order_by() analog isn't available since
.select_related() means "select all related to max depth of 5". So
we'd need a .select_related(depth=0) or similar.

So, each call would resolve to a list of fields. depth=1 would be
shorthand for finding all the fields at depth of 1 and adding it to
the set of previously .select_related fields.

Do people agree this is desirable? I can see that this would be
backwards-incompatible since some people might be knowingly and
intentionally narrowing the previous calls with a shorter/shallower
call. So then perhaps a "from __future__" sort of mechanism,
.select_related(additive=True) or
QuerySet(additive_select_related=True) or similar.

Or, if .select_related should not be additive, I'd like to see 1) docs
improved in this area and/or 2) a warning issued when a previous
.select_related was overridden.

Thoughts?

Javier Guerra Giraldez

unread,
Sep 20, 2011, 1:12:39 PM9/20/11
to django-d...@googlegroups.com
On Tue, Sep 20, 2011 at 11:29 AM, Jeremy Dunck <jdu...@gmail.com> wrote:
> It seems to me that calling .select_related should be additive

+1

--
Javier

Carl Meyer

unread,
Sep 20, 2011, 5:47:53 PM9/20/11
to django-d...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Coincidentally enough, this was just filed a few days ago [1]; after
talking it over with Jacob and Alex in IRC I accepted it, under pretty
much the same logic you just outlined. We thought the
backwards-compatibility issue was negligible, as the current behavior is
undocumented, counter-intuitive, arguably simply a bug, and the
consequences of the change are minor and easy to correct for. So yes, I
agree :-) And I also filed #16856 [2] to address the "no way to clear
it" issue.

Your observation that "depth" is currently sticky while fields are not
is a new one (to me); I'll make a note of that on the ticket.

Carl

[1] https://code.djangoproject.com/ticket/16855
[2] https://code.djangoproject.com/ticket/16856
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk55CgkACgkQ8W4rlRKtE2fGvACaAgEp/MEo5hn65Cf/3Pa1dsLL
0SsAoMw+5d5qQtDswUaI6eXEwx2fn3K2
=uGuP
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages