How to serialize db.Model objects to json?

后端 未结 5 638
-上瘾入骨i
-上瘾入骨i 2020-12-08 07:54

When using

from django.utils import simplejson

on objects of types that derive from db.Model it throws exceptions. How to circ

5条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-08 08:35

    The example provided by Jader Dias works fine for my concern after some twaeking. Remove the encode method as it contains a circular reference. The adjusted class should look like:

    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) 
    

    As I've saved this class in a file called utils.py and when appropriate I import it using

    import utils
    

    Then I just call utils.GqlEncoder().encode(results), for example:

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

    The result should look something like this (I've added some line feeds in order to make it a bit easier to read):

    [
    {"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"
    }
    ]
    

提交回复
热议问题