Overriding/blocking __set__ on db.Property to enforce an alternate set method/process
I'm trying to sub-class db.Property
and override the set method to implement stuff like pre and post set logic.
The problem is that __set__
is being called directly on the property by db.Model.__init__()
during the from_entity
conversion of entity to instance (after it comes out of the datastore), so obviously pre and post set logic should not be called.
class MyProperty(db.StringProperty):
def __set__(model_instance, value):
self.pre_set(value)
super(MyProperty.__set__(model_instance, value)
self.post_set(value)
class MyModel(db.Model):
foo = MyProperty()
my_model = MyModel()
my_model.put()
my_model.foo = u'A new string.' """pre/post set logic runs."""
#onload the __set__ method will be called again
loaded_model = db.get(my_model.key())
# In db.Model.__init__()
for prop in self.pr开发者_JAVA百科operties().values():
value = kwargs.get(prop.name, None) or prop.default() #or something like that
prop.__set__(self, value) """pre/post set logic also runs :("""
How can I differentiate between these two occurrences without having to override db.Model.__init__()
? or should I just do that? Am I not supposed to be doing this with prop.__set__()
?
Unfortunately, there's no easy way to distinguish the two situations. You could examine the stack, but that's an extremely kludgy approach. You could override Model.__init__
- either by monkeypatching it or by requiring users of your property extend your custom model subclass - but I'm not sure how you'd modify it in a way that would help yet remain backwards compatible with existing property classes.
You might want to check out Guido's NDB project - it may be more flexible in this respect, and is still under active development.
精彩评论