The "simple" answer seems to be "override the db class." That's
totally off the top of my head, and it may be completely unrealistic.
Something like (totally untested and almost definitely wrong. Consider
it pseudo-code):
class my_db(google.ext.db):
def put(self, *objects, **kwargs):
for o in objects:
o.pre_put()
super(google.ext.db, self).put(*objects, **kwargs)
Then the models that were overriding put() could put that override
code in pre_put() instead (and change put() to just call that before
calling super().put()...).
You'd have to juggle the nuances of things like post_put(), and any
side-effects. But it seems like a reasonable compromise.