2013-09-02 4 views
5

Ich mag, wie die JsonProperty automatisch eine Python-Struktur in JSON kodiert, wenn die Eigenschaft in den Datenspeicher gesetzt wird, und es automatisch dekodiert wenn sie abgerufen werden. Es wäre jedoch nett, diese JSON-Daten an einen Webbrowser zu senden, ohne sie erneut codieren zu müssen. Gibt es eine Möglichkeit, die rohen JSON-Daten zu erhalten (das heißt, die Decodierung zu verhindern)?App Engine Rückkehr JSON von JsonProperty

class DataForBrowser(ndb.Models) 
    json = ndb.JsonProperty() 

    def get_json(self): 
     return ??? 

Antwort

5

Also, was Sie wollen, ist ein dict zu haben, die codiert wird, wenn auf den Datenspeicher gespeichert, sondern auf Abruf nicht decodiert ... Was „unter der Haube“ ist passiert, dass ein JsonProperty eine Unterklasse von BlobProperty ist, dass wird jedes Mal, wenn es in den Datenspeicher geschrieben wird, codiert (json.dumps()) und jedes Mal, wenn es gelesen wird, dekodiert (json.loads()). Dies kann nur mit einem property subclass erfolgen, die eine dieser Funktionen eliminiert (aber ich glaube nicht, dass es klug ist, unterschiedliche Verhaltensweisen für die Eigenschaft zu haben, nach dem Stand der Einheit ist). Nur für „pädagogische Zwecke“ mal sehen, was dann

from google.appengine.ext import ndb 
import json 

class ExtendedJsonProperty(ndb.BlobProperty): 
    def _to_base_type(self, value): 
    return json.dumps(value) 

    def _from_base_type(self, value): 
    return value 
    # originally return json.loads(value) 

class DataForBrowser(ndb.Model): 
    json = ExtendedJsonProperty() 


data = {'a': 'A'} 
data_for_browser = DataForBrowser() 
data_for_browser.json = data 
print type(data_for_browser.json) # returns <type 'dict'> 
data_for_browser.put() 
print type(data_for_browser.json) # returns <type 'str'> 
data_for_browser_retrieverd = DataForBrowser.query().get() 
print type(data_for_browser_retrieverd.json) # returns <type 'str'> 

passieren wird, wenn Sie die Verwendung des dict in Ihrem Code vornehmen müssen, dann schlage ich mit einem JsonProperty und eine neue Eigenschaft Methode hinzufügen, die das dict zurück als JSON und benutze das.

@property 
def json_as_json(self): 
    return json.dumps(self.json) 

Wenn Sie die dict verwenden nur die JSON-Daten erstellen verwenden Sie dann nur eine BlobProperty und durch json.dumps() bevor die Daten an die Eigenschaft zuweisen

+1

Ja, das ähnlich ist zu was ich gerade mache. Ich frage mich, ob es eine "Hintertür" -Methode (wie eine Hook-Methode) gibt, die einfach die JSON-Zeichenfolge von einer "JsonProperty" zurückgibt. Es scheint rückwärts zu gehen, um die 'ExtendedJsonProperty' einzuführen. –

+1

Ich glaube nicht, dass dies möglich ist, da die Methode _from_base_type() direkt nach dem Abrufen der Daten vom Datenspeicher aufgerufen wird. Von diesem Zeitpunkt an sind die Originaldaten nicht mehr zugänglich. – nizz

+1

Das ist nicht die Antwort, die ich wollte, aber ich denke, es ist die richtige Antwort. –