方法非常简单,用isinstance函数识别出变量类型,递归调用函数分解到原子类型的变量,序列化。
缺点是递归调用会有函数栈,复杂的对象可能占用较大内存
"""
继承自simplejson的编码基类,用于处理复杂类型的编码
"""
def JsonCode(obj):
def _any(obj):
ret = None
#debug('temp',type(obj),obj)
#查询结果集处理
if isinstance(obj,QuerySet):
ret = _list(obj)
#单个结果处理
elif isinstance(obj,models.Model):
ret = _model(obj)
#list处理
elif isinstance(obj,list):
ret = _list(obj)
#字典处理,字典还是需要处理
elif isinstance(obj,dict):
#ret = obj#_dict(obj)
ret = _dict(obj)
#日期时间类型转换
elif isinstance(obj,datetime.datetime):
ret = obj.strftime('%Y-%m-%d %H:%M:%S')
#日期类型转换
elif isinstance(obj,datetime.date):
ret = obj.strftime('%Y-%m-%d')
#字符串或者unicode编码的直接返回
elif isinstance(obj, str) or isinstance(obj, unicode):
ret = obj
else:
ret = str(obj)
return ret
#model
def _model(obj):
ret = {}
for item in obj._meta.fields:
#id不要返回,外键怎么处理?
#if item.attname == 'id':
# continue
ret[item.attname] = _any(getattr(obj, item.attname))
return ret
def _list(obj):
ret = []
for item in obj:
ret.append(_any(item))
return ret
def _dict(obj):
#20160429 修改ret=[] 为 ret={},因为需要返回的数据是字典
ret = {}
# _dict {'Name': 'Zara', 'Age': 7}
#Items() -> [('Age', 7), ('Name', 'Zara')]
for k,v in obj.items():
#print k,v
ret[k] = _any(v)
return ret
#调用_any主入口,返回字典
return _any(obj)