首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将db.Model对象序列化为json?

如何将db.Model对象序列化为json?
EN

Stack Overflow用户
提问于 2010-01-22 10:53:42
回答 4查看 12.7K关注 0票数 19

在使用时

代码语言:javascript
复制
from django.utils import simplejson

对于从db.Model派生的类型的对象,它会抛出异常。如何规避这一点?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-01-24 03:26:19

由于找不到合适的解决方案,我编写了自己的解决方案,它不完全是JSON序列化程序,而是Javascript序列化程序

代码语言: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) + '}'
票数 0
EN

Stack Overflow用户

发布于 2010-02-25 18:07:40

Jader Dias提供的示例在经过一些调整后可以很好地满足我的关注。移除encode方法,因为它包含循环引用。调整后的类应该如下所示:

代码语言:javascript
复制
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的文件中,并在适当的时候使用

代码语言:javascript
复制
import utils

然后我调用utils.GqlEncoder().encode(results),例如:

代码语言:javascript
复制
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) )

结果应该如下所示(我添加了一些换行符,以使其更容易阅读):

代码语言:javascript
复制
[
{"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": "jd@domain.net", 
"full_name": "John Doe"
}
]
票数 10
EN

Stack Overflow用户

发布于 2010-01-22 12:07:08

除了基本类型之外,json不能用于序列化任何类型,如dict、list、int/long和string(这并不全面)。例如,即使这些简单的命令也不起作用:

代码语言:javascript
复制
import json
json.dumps(object())

如果您想序列化django对象,您应该参考django documentation on serialization,它将使用自己的库,但它们确实支持json。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2114659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档