2013-09-02 10 views
5

Mi piace come lo JsonProperty codifica automaticamente una struttura Python in JSON quando la proprietà viene inserita nell'archivio dati e automaticamente la decodifica quando viene recuperata. Tuttavia, sarebbe bello inviare i dati JSON a un browser Web senza doverlo ricodificare nuovamente. C'è un modo per ottenere i dati JSON grezzi (cioè, prevenire la decodifica)?App Engine restituisce JSON da JsonProperty

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

    def get_json(self): 
     return ??? 

risposta

5

Quindi, ciò che si desidera è di avere un dict che viene codificato quando salvato l'archivio dati, ma non decodificato su di recuperarlo ... Che cosa accade "sotto il cofano" è che un JsonProperty è una sottoclasse di BlobProperty che viene codificato (json.dumps()) ogni volta che viene scritto sul datastore e decodificato (json.loads()) ogni volta che viene letto. Questo può essere fatto solo con un property subclass che elimina una di queste funzioni (ma non penso sia saggio avere comportamenti diversi per la proprietà in base allo stato dell'entità). Solo per "scopi educativi" vediamo cosa succederà allora

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'> 

Se avete bisogno di fare uso del dict nel codice allora io suggerisco di usare un JsonProperty e l'aggiunta di un nuovo metodo di proprietà che restituirà il dict come JSON e usa quello.

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

Se si utilizza il dict solo per creare i dati JSON poi basta usare un BlobProperty e passare attraverso json.dumps() prima di assegnare i dati alla proprietà

+1

Sì, è simile a cosa sto facendo attualmente ora. Mi chiedo se esiste un metodo "back door" (come un metodo Hook) che restituirà semplicemente la stringa JSON da un 'JsonProperty'. Sembra di tornare indietro per introdurre 'ExtendedJsonProperty'. –

+1

Non penso che questo sia possibile poiché il metodo _from_base_type() viene chiamato subito dopo che i dati sono stati recuperati dal datastore. Da quel momento in poi, i dati originali non sono più accessibili. – nizz

+1

Questa non è la risposta che volevo, ma penso che sia la risposta corretta. –