2016-06-10 8 views
0

ich _post_put_hook() auf einem meiner NDB Modelle außer Kraft gesetzt haben und ich mag die Art, wie ich mein Ergebnis ändern, auf der URL, um die ursprüngliche Anforderung je verarbeiten gemacht wurde:Mit Blick Kontext in _post_put_hook Modell

def _post_put_hook(self, future): 
    key = future.get_result() 
    # Do some processing 
    if <model was made thanks to POST call to /foo>: 
     # Do one thing 
    else: 
     # Do another 

I Ich weiß, das ist ein bisschen hässlich und überbrückt die große Kluft zwischen API und den zugrunde liegenden DB-Modellen, aber nichtsdestotrotz ist es das, was ich erreichen möchte.

Ich kann nicht an eine gute, asynchrone Methode denken, um dies zu erreichen. Was vermisse ich?

Antwort

0

Ich löste dies in haben (was ich glaube) ist ein asynchroner sichere Art und Weise, wie folgt:

Nach Ansicht I _post_put_hook() Verhalten geändert haben wollen, wo die Zukunft instanziiert wird:

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

Da ist in meinem _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

Wie setzt man ein 'internes' (_) Attribut in der Modellinstanz als Flag, String oder Funktion für den Post Hook? Das Attributfeld wird von NDB ignoriert, wenn die Daten beibehalten werden.

zB:

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 

zB:

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

Sie auch eine Funktion stattdessen zB

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

Wo 'foo' und 'bar' sind normale Funktionen nutzen könnten.

Dann:

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 

Bezüglich async Sicherheit, sollte es kein Problem sein, das interne Attribut (es sei denn, dieselbe Instanz gleichzeitig an anderer Stelle verwendet wird).

+0

Hey, Vielen dank für solch eine ausführliche Antwort! Wie Sie in Ihrem letzten Satz erwähnen, ist dies technisch asynchron sicher nicht, wenn ich zum Beispiel zwei Anfragen für dasselbe Objekt erhalte, das ich anders verarbeiten möchte, oder? Ich habe gerade eine andere Lösung implementiert, die, obwohl sie immer noch etwas hacky ist, mein Problem löst (ich werde es bald aufschreiben). Danke noch einmal – DaveBensonPhillips