2013-09-02 38 views
5

Tôi thích cách JsonProperty tự động mã hóa cấu trúc Python thành JSON khi thuộc tính được đưa vào kho dữ liệu và tự động giải mã khi truy xuất. Tuy nhiên, sẽ tốt hơn nếu gửi dữ liệu JSON đó tới trình duyệt web mà không phải mã hóa lại. Có cách nào để có được dữ liệu JSON thô (có nghĩa là, ngăn chặn việc giải mã) không?App Engine trả về JSON từ JsonProperty

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

    def get_json(self): 
     return ??? 

Trả lời

5

Vì vậy, những gì bạn muốn là phải có một dict đó được mã hóa khi lưu vào kho dữ liệu nhưng không được giải mã khi lấy nó ... Chuyện gì xảy ra "dưới mui xe" là một JsonProperty là một lớp con của BlobProperty rằng được mã hóa (json.dumps()) mỗi khi nó được ghi vào kho dữ liệu và giải mã (json.loads()) mỗi khi nó được đọc. Điều này chỉ có thể được thực hiện với một số property subclass để loại bỏ một trong các chức năng này (nhưng tôi không nghĩ rằng có những hành vi khác nhau cho tài sản theo trạng thái của pháp nhân). Chỉ cần cho "mục đích giáo dục" chúng ta hãy xem những gì sẽ xảy ra sau đó

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

Nếu bạn cần phải tận dụng các dict trong mã của bạn sau đó tôi đề nghị sử dụng một JsonProperty và thêm một phương pháp tài sản mới mà sẽ trả lại dict dưới dạng JSON và sử dụng nó.

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

Nếu bạn sử dụng dict chỉ để tạo ra các dữ liệu JSON sau đó chỉ cần sử dụng một BlobProperty và đi qua json.dumps() trước khi gán các dữ liệu đến tài sản

+1

Vâng, đó là tương tự như những gì tôi hiện đang làm. Tôi tự hỏi nếu có một phương thức "back door" (giống như một phương thức Hook) sẽ trả về chuỗi JSON từ một 'JsonProperty'. Nó có vẻ như ngược lại để giới thiệu 'ExtendedJsonProperty'. –

+1

Tôi không nghĩ rằng điều này là có thể vì phương thức _from_base_type() được gọi ngay sau khi dữ liệu được lấy từ kho dữ liệu. Từ thời điểm đó, dữ liệu ban đầu không thể truy cập được nữa. – nizz

+1

Đó không phải là câu trả lời tôi muốn, nhưng tôi nghĩ đó là câu trả lời đúng. –