복붙노트

[PYTHON] db.Model 객체를 json으로 직렬화하는 방법?

PYTHON

db.Model 객체를 json으로 직렬화하는 방법?

사용할 때

from django.utils import simplejson

db.Model에서 파생 된 유형의 객체에 대해서는 예외가 발생합니다. 이걸 우회하는 방법?

해결법

  1. ==============================

    1.좋아, 파이썬은별로 도움이되지 않을 것입니다. 파서를 쓸 필요가 없습니다. 해결책입니다.

    좋아, 파이썬은별로 도움이되지 않을 것입니다. 파서를 쓸 필요가 없습니다. 해결책입니다.

    이 utlity 클래스 추가 http://code.google.com/p/google-app-engine-samples/source/browse/trunk/geochat/json.py?r=55

     import datetime  
     import time 
    
     from google.appengine.api import users 
     from google.appengine.ext import db 
    
    #this is a mod on the orinal file for some reason it includes its own simplejson files i have ref django!
     from django.utils import simplejson  
    
     class GqlEncoder(simplejson.JSONEncoder): 
    
       """Extends JSONEncoder to add support for GQL results and properties. 
    
       Adds support to simplejson JSONEncoders for GQL results and properties by 
       overriding JSONEncoder's default method. 
       """ 
    
       # TODO Improve coverage for all of App Engine's Property types. 
    
       def default(self, obj): 
    
         """Tests the input object, obj, to encode as JSON.""" 
    
         if hasattr(obj, '__json__'): 
           return getattr(obj, '__json__')() 
    
         if isinstance(obj, db.GqlQuery): 
           return list(obj) 
    
         elif isinstance(obj, db.Model): 
           properties = obj.properties().items() 
           output = {} 
           for field, value in properties: 
             output[field] = getattr(obj, field) 
           return output 
    
         elif isinstance(obj, datetime.datetime): 
           output = {} 
           fields = ['day', 'hour', 'microsecond', 'minute', 'month', 'second', 
               'year'] 
           methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 
               'timetuple'] 
           for field in fields: 
             output[field] = getattr(obj, field) 
           for method in methods: 
             output[method] = getattr(obj, method)() 
           output['epoch'] = time.mktime(obj.timetuple()) 
           return output 
    
         elif isinstance(obj, time.struct_time): 
           return list(obj) 
    
         elif isinstance(obj, users.User): 
           output = {} 
           methods = ['nickname', 'email', 'auth_domain'] 
           for method in methods: 
             output[method] = getattr(obj, method)() 
           return output 
    
         return simplejson.JSONEncoder.default(self, obj) 
    
    
     def encode(input): 
       """Encode an input GQL object as JSON 
    
         Args: 
           input: A GQL object or DB property. 
    
         Returns: 
           A JSON string based on the input object.  
    
         Raises: 
           TypeError: Typically occurs when an input object contains an unsupported 
             type. 
         """ 
       return GqlEncoder().encode(input)   
    

    json.py로 저장

    쓰다

    import cgi
    import os
    import json 
    
    from google.appengine.ext.webapp import template
    from google.appengine.api import users
    from google.appengine.ext import webapp
    from google.appengine.ext.webapp.util import run_wsgi_app
    from google.appengine.ext import db
    
    
    class Greeting(db.Model):
        author = db.UserProperty()
        content = db.StringProperty(multiline=True)
        date = db.DateTimeProperty(auto_now_add=True)
    
    class MainPage(webapp.RequestHandler):
        def get(self):
            greetings_query = Greeting.all().order('-date')
            greetings = greetings_query.fetch(5)
    
            if users.get_current_user():
                url = users.create_logout_url(self.request.uri)
                url_linktext = 'Logout'
            else:
                url = users.create_login_url(self.request.uri)
                url_linktext = 'Login'
    
            template_values = {
                'greetings': greetings,
                'url': url,
                'url_linktext': url_linktext,
                }
    
            path = os.path.join(os.path.dirname(__file__), 'index.html')
            self.response.out.write(template.render(path, template_values))
    
    
    class Guestbook(webapp.RequestHandler):
        def post(self):
            greeting = Greeting()
    
            if users.get_current_user():
                greeting.author = users.get_current_user()
    
            greeting.content = self.request.get('content')
            greeting.put()
            self.redirect('/')
    
    
    
    #here i return my json feed - simple implementaion for example
    class FeedHandler(webapp.RequestHandler):
    
      def get(self):
        """Retrieve a feed"""
        user = None
    
        greetings_query = Greeting.all().order('-date')
        rs= greetings_query.fetch(5)
    #this is the part that calls the encoder - dosnt cause an exception
        data = json.encode(rs)
    
    
    
    #roll out to browser -might need to check my headers etc
        self.response.headers['Content-Type'] = 'application/json; charset=utf-8'  
        self.response.out.write(data)
    
    
    
    
    application = webapp.WSGIApplication(
                                           [
                                           ('/', MainPage),
                                           ('/sign',Guestbook),
                                           ('/feed',FeedHandler),
                                           ], debug=True
                                        )
    
    def main():
        run_wsgi_app(application)
    
    if __name__ == "__main__":
        main()
    

    브라우저 응답입니다.

  2. ==============================

    2.Jader Dias가 제공 한 예제는 일부 twaeking 후 내 관심사에 대해 잘 작동합니다. 원형 참조가 포함되어 있으므로 encode 메서드를 제거하십시오. 조정 된 클래스는 다음과 같아야합니다.

    Jader Dias가 제공 한 예제는 일부 twaeking 후 내 관심사에 대해 잘 작동합니다. 원형 참조가 포함되어 있으므로 encode 메서드를 제거하십시오. 조정 된 클래스는 다음과 같아야합니다.

    import datetime  
    import time 
    
    from google.appengine.api import users 
    from google.appengine.ext import db 
    from django.utils import simplejson  
    
    
    class GqlEncoder(simplejson.JSONEncoder): 
    
        """Extends JSONEncoder to add support for GQL results and properties. 
    
        Adds support to simplejson JSONEncoders for GQL results and properties by 
        overriding JSONEncoder's default method. 
        """ 
    
        # TODO Improve coverage for all of App Engine's Property types. 
    
        def default(self, obj): 
    
            """Tests the input object, obj, to encode as JSON.""" 
    
            if hasattr(obj, '__json__'): 
                return getattr(obj, '__json__')() 
    
            if isinstance(obj, db.GqlQuery): 
                return list(obj) 
    
            elif isinstance(obj, db.Model): 
                properties = obj.properties().items() 
                output = {} 
                for field, value in properties: 
                    output[field] = getattr(obj, field) 
                return output 
    
            elif isinstance(obj, datetime.datetime): 
                output = {} 
                fields = ['day', 'hour', 'microsecond', 'minute', 'month', 'second', 'year'] 
                methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 'timetuple'] 
                for field in fields: 
                    output[field] = getattr(obj, field) 
                for method in methods: 
                    output[method] = getattr(obj, method)() 
                output['epoch'] = time.mktime(obj.timetuple()) 
                return output
    
            elif isinstance(obj, datetime.date): 
                output = {} 
                fields = ['year', 'month', 'day'] 
                methods = ['ctime', 'isocalendar', 'isoformat', 'isoweekday', 'timetuple'] 
                for field in fields: 
                    output[field] = getattr(obj, field) 
                for method in methods: 
                    output[method] = getattr(obj, method)() 
                output['epoch'] = time.mktime(obj.timetuple()) 
                return output 
    
            elif isinstance(obj, time.struct_time): 
                return list(obj) 
    
            elif isinstance(obj, users.User): 
                output = {} 
                methods = ['nickname', 'email', 'auth_domain'] 
                for method in methods: 
                    output[method] = getattr(obj, method)() 
                return output 
    
            return simplejson.JSONEncoder.default(self, obj) 
    

    utils.py라는 파일에이 클래스를 저장 했으므로 적절한 경우이 클래스를 사용하여 가져옵니다.

    import utils
    

    그런 다음 utils.GqlEncoder (). encode (results)를 호출합니다. 예를 들면 다음과 같습니다.

    query = User.all()
    results = query.fetch(10)
    
    self.response.headers['Content-Type'] = "text/plain" # Alt. application/json
    self.response.out.write( utils.GqlEncoder().encode(results) )
    

    결과는 다음과 같이 보일 것입니다. (읽기 쉽도록 줄 바꿈을 추가했습니다) :

    [
    {"date": {"ctime": "Tue Feb 23 10:41:21 2010", "hour": 10, "isoweekday": 2, "month": 2, 
            "second": 21, "microsecond": 495535, "isocalendar": [2010, 8, 2], "timetuple": [2010, 2, 23, 10, 41, 21, 1, 54, -1], 
            "year": 2010, "epoch": 1266921681.0, "isoformat": "2010-02-23T10:41:21.495535", "day": 23, "minute": 41}, 
    "claimed_id": "https:\/\/www.google.com\/accounts\/o8\/id?id=abcdefghijklmnopqrstuvxyz", 
    "display_name": "Alfred E Neumann", 
    "email": null, 
    "full_name": "Alfred E Neumann"
    }, 
    {"date": {"ctime": "Tue Feb 23 11:00:54 2010", "hour": 11, "isoweekday": 2, "month": 2, 
            "second": 54, "microsecond": 805261, "isocalendar": [2010, 8, 2], "timetuple": [2010, 2, 23, 11, 0, 54, 1, 54, -1], 
            "year": 2010, "epoch": 1266922854.0, "isoformat": "2010-02-23T11:00:54.805261", "day": 23, "minute": 0}, 
    "claimed_id": "http:\/\/openid.domain.net\/john", 
    "display_name": "", 
    "email": "jp@domain.net", 
    "full_name": "John Parnefjord"
    }
    ]
    
  3. ==============================

    3.json은 dicts,리스트, ints / longs 및 문자열과 같은 기본 유형보다 더 많은 것을 직렬화하는 데 사용할 수 없습니다 (포괄적이지는 않습니다). 예를 들어, 다음의 간단한 명령조차도 작동하지 않습니다.

    json은 dicts,리스트, ints / longs 및 문자열과 같은 기본 유형보다 더 많은 것을 직렬화하는 데 사용할 수 없습니다 (포괄적이지는 않습니다). 예를 들어, 다음의 간단한 명령조차도 작동하지 않습니다.

    import json
    json.dumps(object())
    

    django 객체를 직렬화하려면 자체 라이브러리를 사용할 직렬화에 대한 장고 문서를 참조해야하지만 json을 지원해야합니다.

  4. ==============================

    4.이후 적절한 솔루션을 찾을 수 없기 때문에 JSON 시리얼 라이저는 아니지만 Javascript 시리얼 라이저

    이후 적절한 솔루션을 찾을 수 없기 때문에 JSON 시리얼 라이저는 아니지만 Javascript 시리얼 라이저

    from google.appengine.ext import db
    from google.appengine.api.datastore_types import *
    
    def dumpStr(obj):
        return "'" + obj + "'"
    
    def dumps(obj):
        if isinstance(obj, str):
            return dumpStr(obj)
        elif obj == None:
            return None
        elif isinstance(obj, list):
            items = [];
            for item in obj:
                items.append(dumps(item))
            return '[' + ','.join(items) + ']'
        elif isinstance(obj, datetime.datetime):
            return "new Date('%s')" % obj.ctime()
        properties = [];
        for property in dir(obj):
            if property[0] != '_':
                value = obj.__getattribute__(property)
                valueClass = str(value.__class__)
                if not(('function' in valueClass) or ('built' in valueClass) or ('method' in valueClass)):
                    value = dumps(value)
                    if value != None:
                        properties.append("'" + property + "':" + value)
        if len(properties) == 0:
            return str(obj)
        else:
            return '{' + ','.join(properties) + '}'
    
  5. ==============================

    5.내가 이해할 수있는 - 그리고 나는 python에 익숙하다 - 구글 앱 엔진을 사용하면 모델 객체를 dictioanry python 객체로 직렬화 한 다음 간단한 json을 사용하여 json 문자열로 덤프 할 수있다. - 어쩌면 누군가가 ditionary에 연재 할 줄 아는 사람이있을 것입니다 (pickel?). 이것에 대한 도움은 도움이 될 것입니다! 구글 앱 엔진에는 이것에 대한 inbuilt 솔루션이 없다는 것을 감동하지 않아야한다.

    내가 이해할 수있는 - 그리고 나는 python에 익숙하다 - 구글 앱 엔진을 사용하면 모델 객체를 dictioanry python 객체로 직렬화 한 다음 간단한 json을 사용하여 json 문자열로 덤프 할 수있다. - 어쩌면 누군가가 ditionary에 연재 할 줄 아는 사람이있을 것입니다 (pickel?). 이것에 대한 도움은 도움이 될 것입니다! 구글 앱 엔진에는 이것에 대한 inbuilt 솔루션이 없다는 것을 감동하지 않아야한다.

  6. from https://stackoverflow.com/questions/2114659/how-to-serialize-db-model-objects-to-json by cc-by-sa and MIT license