概念:何为序列化反序列化
每种编程语言都有各自的数据类型, 将属于自己语言的数据类型或对象转换为可通过网络传输或可以存储到本地磁盘的数据格式(如:XML、JSON或特定格式的字节串)的过程称为序列化(seralization);反之则称为反序列化。
1. 序列化/反序列化需要使用python中的json库中的四个方法:dumps、dump、loads、load。
2. python中的字典、列表、元祖可以使用dumps直接序列化
import json
# 1. json.dumps的用法
"""
# dumps的几个常用参数ident、separators、ensure_ascii、sort_keys
# ident:缩进几个字符,separators:设置分隔符,ensure_ascii:非ascii字符是否解码,sort_keys:是否排序
info_dict = {"name": "马亚南", "age": 28}
print(type(info_dict))
# 将字典转换为json数据:json.dumps
info_json = json.dumps(info_dict, indent=2, separators=(",", ":"),
ensure_ascii=False, sort_keys=True)
print(type(info_json))
print(info_json)
# 将json数据保存到文件中
f = open("info_json", "w")
f.write(info_json)
f.close()
"""
# 2. json.dump的用法
"""
info_dict = {"name": "马亚南", "age": 28}
with open("info_json", "w") as f:
# 将字典转换成json数据并写入文件中
json.dump(info_dict, f, ensure_ascii=False)
"""
# 3. json.loads的用法
"""
info_json = '{"name": "mayanan", "age": 28}'
# 将json数据转换成字典
info_dict = json.loads(info_json)
"""
# 4. json.load的用法
"""
with open("info_json", "r") as f:
info_dict = json.load(f)
""
3. 而集合需要转换成列表,日期和日期时间需要转换成字符串在进行序列化
# 如何将python中的集合序列化
"""
def set_to_list(obj):
if isinstance(obj, set):
return list(obj)
return TypeError
set_data = {'my_set', "2"}
info_json = json.dumps(set_data, default=set_to_list)
print(type(info_json))
print(info_json)
"""
# 如何将python中的日期/日期时间序列化
"""
def date_to_str(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
elif isinstance(obj, date):
return obj.strftime("%Y-%m-%d")
raise TypeError
info_now = datetime.now()
info_json = json.dumps({"now": info_now}, default=date_to_str)
print(type(info_json))
print(info_json)
"""
4. 对于我们自定义的类, 使用dumps方法时我们一般要先编写obj_to_dict方法,将object转化为字典dict再JSON序列化。同理,使用loads方法对json数据反序列化时,我们还需要编写dict_to_obj方法,通过default参数调用。
# 将自定义的类转化为字典,dumps方法使用
def obj_to_dict(obj):
d = {}
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d
# 将字典转化为自定义的类,loads方法使用
def dict_to_obj(d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
class_ = getattr(module, class_name)
args = dict((key.encode('ascii'), value) for key, value in d.items())
instance = class_(**args)
else:
instance = d
return instance
5. django中的QuerySet、ValuesQuerySet如何进行序列化
使用serializers类可以轻易将QuerySet格式的数据转化为json格式。
# Django Queryset数据 to Json
from django.core import serializers
data = serializers.serialize("json", SomeModel.objects.all())
data1 = serializers.serialize("json", SomeModel.objects.all(), fields=('name','id'))
data2 = serializers.serialize("json", SomeModel.objects.filter(field = some_value))
有时候我们只需要查询结果集的部分字段,可以使用values('字段名','字段名2')来要求返回的是哪些列的数据.但是返回来的是ValuesQuerySet对象而不是QuerySet对象。ValuesQuerySet对象不能用 serializers.serialize() 方法序列化成json, 需要先转换成list再用 json.dumps()方法序列化成json格式。示例代码如下所示:
import json
from django.core.serializers.json import DjangoJSONEncoder
queryset = myModel.objects.filter(foo_icontains=bar).values('f1', 'f2', 'f3')
data4 = json.dumps(list(queryset), cls=DjangoJSONEncoder)