﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
31680	Preventing DeferredAttribute .__ get__ method unnecessary calls	Sultan	nobody	"To retrieve a deferred model attributes, the __get__ method is called twice. This is because it uses the getattr() function, which in turn causes the __get__ method to be called again.


{{{
    def __get__(self, instance, cls=None):
        """"""
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        """"""
        if instance is None:
            return self
        data = instance.__dict__
        field_name = self.field.attname
        if field_name not in data:
            # Let's see if the field is part of the parent chain. If so we
            # might be able to reuse the already loaded value. Refs #18343.
            val = self._check_parent_chain(instance)
            if val is None:
                instance.refresh_from_db(fields=[field_name])
                **val = getattr(instance, field_name)**
            data[field_name] = val
        return data[field_name]
}}}


To prevent this unnecessary call, we can simply extract the value from the instance dict (at that moment it already contains the searched value):


{{{
    def __get__(self, instance, cls=None):
        """"""
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        """"""
        if instance is None:
            return self
        data = instance.__dict__
        field_name = self.field.attname
        if field_name not in data:
            # Let's see if the field is part of the parent chain. If so we
            # might be able to reuse the already loaded value. Refs #18343.
            val = self._check_parent_chain(instance)
            if val is None:
                instance.refresh_from_db(fields=[field_name])
                # Now the instance dict contains the reloaded data.
                # Using getattr() will do extra call to __get__ method.
                **val = data[field_name]**
            data[field_name] = val
        return data[field_name]
}}}

This reduces the number of method calls.
"	Cleanup/optimization	new	Database layer (models, ORM)	3.1	Normal				Unreviewed	0	0	0	0	0	0
