This sounds like a reasonable request, I don't yet have an opinion on API
or anything. One tiny thing I'd like to note though, "change DeferredAttribute
to find all *other* DeferredAttributes". I don't think `finding` is the
right way to think about it, a `DeferredAttribute` with loadall semantics
should know about the specific set of objects that came from the queryset.

Alex


On Thu, Apr 25, 2013 at 12:06 PM, Adrian Holovaty <adr...@holovaty.com>wrote:

> At the moment, if you call defer() or only() on a QuerySet, then access
> the deferred fields individually, *each* access of a deferred field will
> result in a separate query.
>
> For example, assuming a User model with username/bio/location fields, this
> is what currently happens:
>
> """
> >>> u = User.objects.only('username').get(id=1)
> # Results in: SELECT id, username FROM users WHERE id=1
>
> >>> u.bio
> # Results in SELECT bio FROM users WHERE id=1
>
> >>> u.location
> # Results in SELECT location FROM users WHERE id=1
> """
>
> I'd like there to be a way of retrieving *all* deferred fields the first
> time a deferred field is accessed. So with the above example, this would
> happen instead:
>
> """
> >>> u = User.objects.only('username').get(id=1)
> # Results in: SELECT id, username FROM users WHERE id=1
>
> >>> u.bio
> # Results in SELECT bio, location FROM users WHERE id=1
>
> >>> u.location
> # No database query
> """
>
> Here's my use case. In my app, I'm storing frequently accessed user
> attributes (id, username, etc.) in signed cookies, to prevent an
> unnecessary database hit on every page view. I create a User object with
> those attributes, so that I can take advantage of various methods on the
> User class, but I want the other User fields to be lazily loaded. I have
> this all working except for the last piece, which is to change lazy loading
> such that it loads *everything* else the first time a deferred field is
> accessed.
>
> So that's the "what" and "why" -- here's the how...
>
> The current implementation is in django/db/models/query_utils.py -- see
> the DeferredAttribute class. When you call only() or defer() on a QuerySet,
> the resulting model instance will have a DeferredAttribute instance for
> each deferred field. The problem is that DeferredAttributes only load their
> own column's data, not the data for all *other* DeferredAttributes on the
> given model instance. Hence, the individual SQL queries for each column.
>
> To solve this, we would need to change DeferredAttribute to find all
> *other* DeferredAttributes on the given model and load them in a single
> query somehow.
>
> Also, I should mention that this should be *optional* behavior, as the
> current behavior is reasonable for the common case. The API for specifying
> this "load everything" behavior is a separate discussion. Perhaps a keyword
> argument like: User.objects.only('username', loadall=True).
>
> Thoughts?
>
> Adrian
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers?hl=en
> .
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>



-- 
"I disapprove of what you say, but I will defend to the death your right to
say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
"The people's good is the highest law." -- Cicero
GPG Key fingerprint: 125F 5C67 DFE9 4084

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to