I'm looking to implement a property class for appengine, very similar to the existing db.ReferenceProperty
. I am implementing my own version because I want some other default return values. My question is, how do I make the property remember its returned value, so that the datastore query is only performed the first time the property is fetched? What I had is below, and it does not work. I read that the Property classes do not belong to the instances, but to the model definition, so I guess that the return value is not cached for each instance, but overwritten on the model every time. Where should I store this _resolved
variable?
class PageProperty(db.Property):
data_type = Page
def get_value_for_datastore(self, model_instance):
page = super(PageProperty, self).get_value_for_datastore(model_instance)
self._resolved = page
return page.key().name()
def make_value_from_datastore(self, value):
if not hasattr(self, '_resolved'):
self._resolved = Page.get_by_name(value)
return self._resolved
Edit
Alex' answer is certainly usable. But it seems that the built-in db.ReferenceProperty
does store the _RESOLVED
variable on the model instance. As evidenced by:
[...]
setattr(model_instance, self.__resolved_attr_name(), value)
[...]
def __resolved_attr_name(self):
return '_RESOLVED' + self._attr_name()
The get_value_for_datastore
method is passed the model instance, but make_value_from_datastore
is not, so how do they find the _RESOLVED
property from that method?
Edit 2
From the code I gather that google is using the __get__()
and __set__()
methods, both of which do get the model instance as an argument. Are those usable in custom classes? What is the difference with get_value_for_datastore
and its counterpart?