2013-09-02 10 views
5

Podoba mi się, jak JsonProperty automatycznie koduje strukturę Pythona do JSON, gdy właściwość jest umieszczana w składnicy danych, i automatycznie dekoduje ją po pobraniu. Jednak byłoby miło wysłać te dane JSON do przeglądarki internetowej bez konieczności ponownego kodowania. Czy istnieje sposób, aby uzyskać surowe dane JSON (to znaczy zapobiec dekodowaniu)?App Engine return JSON z JsonProperty

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

    def get_json(self): 
     return ??? 

Odpowiedz

5

Więc co chcesz to mieć dict który pobiera zakodowany po zapisaniu do magazynu danych, ale nie dekodowane po pobraniu go ... Co dzieje się „pod maską” jest to, że JsonProperty jest podklasą BlobProperty że zostaje zakodowany (json.dumps()) za każdym razem, gdy zostanie zapisany do magazynu danych i zdekodowany (json.loads()) za każdym razem, gdy zostanie odczytany. Można to zrobić tylko za pomocą property subclass, która eliminuje jedną z tych funkcji (ale nie sądzę, że mądrze jest mieć różne zachowania dla właściwości w zależności od stanu, w którym znajduje się jednostka). Tylko dla „celów edukacyjnych” zobaczmy, co się stanie potem

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

Jeśli musisz skorzystać z dict w kodzie to proponuję przy użyciu JsonProperty i dodając nową metodę właściwość, która powróci do dict jako JSON i użyj tego.

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

Jeśli używasz dict tylko do tworzenia danych JSON następnie wystarczy użyć BlobProperty i przechodzą przez json.dumps() przed przypisaniem danych do właściwości

+1

Tak, to jest podobny do co teraz robię teraz. Zastanawiam się, czy istnieje metoda "back door" (jak metoda Hook), która po prostu zwróci ciąg JSON z 'JsonProperty'. Wydaje się, że cofamy się, aby wprowadzić "ExtendedJsonProperty". –

+1

Nie sądzę, że jest to możliwe, ponieważ metoda _from_base_type() jest wywoływana zaraz po pobraniu danych z magazynu danych. Od tego momentu oryginalne dane nie są już dostępne. – nizz

+1

To nie jest odpowiedź, którą chciałem, ale myślę, że to jest poprawna odpowiedź. –