On 12 touko, 19:15, Aymeric Augustin
<[email protected]> wrote:
> > The refresh() method accepts *args, so that one can specify which
> > fields to reload. This is useful so that deferred attribute loading
> > can use refresh(), and by overriding refresh() it will be possible to
> > customize how deferred loading happens.
>
> > Deferred field loading is altered to use .refresh().
>
> I'm not totally following you here. I suppose it would make sense if I were
> more familiar with the implementation.
The deferred attribute implementation is as follows: all deferred
attributes have a DeferredAttribute descriptor (found from
models.query_utils IIRC), so on access of foo.somefield the
descriptor's __get__() is called. The __get__() checks if the value is
already found from the instance, if not it ends up fetching the value
from DB. The fetching of the value is equivalent to refresh() of
somefield (but of course not equivalent to full refresh).
So, if you override refresh() to do this:
def refresh(self, *fields):
if set(fields).intersects(self.deferred_fields):
fields.extend(self.deferred_fields)
super().refresh(*fields)
Now, any time any deferred field is accessed (or refreshed manually),
then all of the deferred attributes are loaded in one go. This will
give a solution to Adrian's request of loading all deferred fields in
one go when one is accessed. Granted, there is no declarative way to
do this, nor is there per-queryset API. I think that cases where there
is need to customize deferred attribute loading are rare, so there is
no need for dedicated API.
In addition the DeferredAttribute implementation will be a little more
DRY.
- Anssi
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.