Django’s serialization framework provides a mechanism for “translating” Django models into other formats. Usually these other formats will be text-based and used for sending Django data over a wire, but it’s possible for a serializer to handle any format (text-based or not).(Django序列化框架提供将模型转换成其他格式的机制,通常转换后的格式主要是用来传输的基于文本的数据,事实上Django能够处理任何数据转换,无论是基于文本的还是非文本的),以下为常用的转换格式:
Identifier | Information |
---|---|
xml | Serializes to and from a simple XML dialect. |
json | Serializes to and from JSON. |
yaml | Serializes to YAML (YAML Ain’t a Markup Language). This serializer is only available if PyYAML is installed. |
If you just want to get some data from your tables into a serialized form, you could use the dumpdata management command.(如果想要直接从数据表中获取数据然后序列化成合适的格式,可以使用dumpdata 管理命令)
以序列化为XML格式的数据为例引入讲解基础知识:
>>> from django.core import serializers
>>> data = serializers.serialize("xml", SomeModel.objects.all())
Subset of fields(子集字段的序列化)
>>> data = serializers.serialize('xml',User.objects.all(), fields=('nickname','first_name','last_name'))
>>> data
'\n<django-objects version="1.0"><object model="userapp.user" pk="lockey23"><field name="first_name" type="CharField">Yangfield><field name="last_name" type="CharField">Chengfield>object>django-objects>'
This is useful if you want to serialize data directly to a file-like object (which includes an HttpResponse):(对于想要将数据序列化为类似文件的对象,可以使用以下方式)
py3) [root@7-o-1 iledu]# python manage.py shell
>>> from userapp.models import User
>>> from django.core import serializers
>>> XMLSerializer = serializers.get_serializer("xml")
>>> xml_serializer = XMLSerializer()
>>> with open("file.xml", "w") as out:
... xml_serializer.serialize(User.objects.all(),stream=out)
(py3) [root@7-o-1 iledu]# cat file.xml
<django-objects version="1.0"><object model="userapp.user" pk="lockey23"><field name="first_name" type="CharField">Yangfield><field name="last_name" type="CharField">Chengfield><field name="email" type="CharField"><None>None>field><field name="password" type="CharField"><None>None>field><field name="role" type="CharField">teammatefield><field name="avatar" type="CharField">/static/avatar/default.jpgfield><field name="created_at" type="DateTimeField"><None>None>field><field name="updated_at" type="DateTimeField"><None>None>field><field name="last_login_at" type="DateTimeField"><None>None>field>object>django-objects>(py3)
Note
Calling get_serializer() with an unknown format will raise a django.core.serializers.SerializerDoesNotExist exception.
在未指定格式化参数的情况下调用get_serializer()将会引发一个django.core.serializers.SerializerDoesNotExist 异常
序列化后的数据格式:
>>> for obj in serializers.deserialize("xml", data):
... print(type(obj))
...
'django.core.serializers.base.DeserializedObject'>
Inherited models(继承模型的序列化)
对于类似以下模型:
class Place(models.Model):
name = models.CharField(max_length=50)
class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
当我们使用以下方法进行序列化的时候:
data = serializers.serialize('xml', Restaurant.objects.all())
the fields on the serialized output will only contain the serves_hot_dogs attribute. The name attribute of the base class will be ignored.(序列化后的输出将只包含serves_hot_dogs 属性,基类的name属性将被忽略),如果想要将基类的属性也进行序列化的话那么应该操作如下:
all_objects = list(Restaurant.objects.all()) + list(Place.objects.all())
data = serializers.serialize('xml', all_objects)
数据的反序列化:
>>> u = User.objects.all()
>>> u
]>
>>> u.delete()
(1, {'userapp.User': 1})
>>> u
>>> for obj in serializers.deserialize("xml", data):
... obj.save()
...
>>> u
]>
As you can see, the deserialize function takes the same format argument as serialize, a string or stream of data, and returns an iterator.(如上所见,反序列化函数接受如序列化一样的参数,一个字符串代表数据格式,以及需要反序列化的数据,结果返回一个迭代器)
我们可以使用:
DeserializedObject.save()【即上栗中的obj.save()】将对象保存到数据库中去
note
The Django object itself can be inspected as deserialized_object.object. If fields in the serialized data do not exist on a model, a DeserializationError will be raised unless the ignorenonexistent argument is passed in as True:
Django 对象自己会检查反序列化的数据是否匹配对应模型,如果不匹配的话,一个DeserializationError 异常将被抛出(条件是ignorenonexistent 参数设置为True),如下例:
serializers.deserialize("xml", data, ignorenonexistent=True)
序列化为json格式:
user_list = serializers.serialize('json', User.objects.all())
对于一些定制类型的数据序列化为json需要做特殊处理,eg:
from django.core.serializers.json import DjangoJSONEncoder
class LazyEncoder(DjangoJSONEncoder):
def default(self, obj):
if isinstance(obj, YourCustomType):
return str(obj)
return super().default(obj)
You can then pass cls=LazyEncoder to the serializers.serialize() function:
from django.core.serializers import serialize
serialize('json', SomeModel.objects.all(), cls=LazyEncoder)
序列化为yaml格式:
pip install PyYAML
>>> from django.core import serializers
>>> from userapp.models import User
>>> data = serializers.serialize('yaml',User.objects.all(), fields=('nickname','first_name','last_name'))
>>> data
'- model: userapp.user\n pk: lockey23\n fields: {first_name: Yang, last_name: Cheng}\n'
>>>