[Fixed]-Using view context in model's _post_put_hook

0👍

I’ve solved this in (what I believe) is an async-safe way as follows:

In the view I want to have modified _post_put_hook() behavior for, where the future is instantiated:

def some_processor(self):
    ...
    future = foo.put_async()
    future.my_flag = True # Add custom flag here
    return future

Then in my _post_put_hook():

def _post_put_hook(self, future):
    key = future.get_result()
    if getattr(future, 'my_flag', False):
        # Do one thing
    else:
        # Do another

1👍

How about setting an ‘internal’ (_) attribute on the model instance as a flag, string or function for the post hook to use? The attribute field will be ignored by NDB when persisting the data.

eg:

class TestModel(ndb.Model):
        xyz = ndb.StringProperty()
        ...

        def _post_put_hook(self, future):
            key = future.get_result()
            # Do some processing
            try:
                fooFlag = self._fooFlag
            except:
              fooFlag = False # default if _fooFlag is not set
            if fooFlag:
                # Do one thing
            else:
                # Do another

eg:

    test = TestModel(xyz='abc', ...)
    test._fooFlag = ... #do your foo URL test here
    test.put()

You could also use a function instead eg

    test = TestModel(xyz='abc', ...)
    test._postFunc = foo if 'foo' in url else 'bar' # etc
    test.put()

Where ‘foo’ and ‘bar’ are normal functions.

Then:

def _post_put_hook(self, future):
      ...
        try:
            func = self._postFunc
        except:
            func = None # no _postFunc set
        if func is not None:
            func(self) # handle exceptions as desired

Regarding async safety, there shouldn’t be any problem using the internal attribute (unless the same instance is used elsewhere concurrently).

Leave a comment