Django的序列化工具让你可以将Django的模型‘翻译’成其它格式的数据。通常情况下,这种其它格式的数据是基于文本的,并且用于数据交换\传输过程。

一、序列化数据

Django为我们提供了一个强大的序列化工具serializers。使用它也很简单,如下所示:

from django.core import serializers
data = serializers.serialize("xml", SomeModel.objects.all())

首先,从djang.core导入它,然后调用它的serialize方法,这个方法至少接收两个参数,第一个是你要序列化成为的数据格式,这里是‘xml’,第二个是要序列化的数据对象,数据通常是ORM模型的QuerySet,一个可迭代的对象。

就是这么简单!!

还有一种比较复杂,但钩子更多的使用方法,如下所示:

XMLSerializer = serializers.get_serializer("xml")
xml_serializer = XMLSerializer()
xml_serializer.serialize(queryset)
data = xml_serializer.getvalue()

主要是使用了serializers的get_serializer()和getvalue()方法。

当你需要将序列化的数据保存到一个文件对象中的时候,上面的方式就非常有用,例如:

with open("file.xml", "w") as out:
xml_serializer.serialize(SomeModel.objects.all(), stream=out)

1. 序列化指定字段

如果你不想序列化模型对象所有字段的内容,只想序列化某些指定的字段,可以使用fields参数,如下所示:

from django.core import serializers
data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))

这样,只有name和size字段会被序列化。但是,有一个例外,模型的主键pk被隐式输出了,虽然它并不包含在fields参数中。

2. 序列化继承模型

考虑下面的模型继承:

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

序列化输出上的字段将只包含serves_hot_dogs属性。基类的name属性并不会一起序列化。

为了完全序列化Restaurant实例,还需要将Place模型序列化,如下所示:

all_objects = list(Restaurant.objects.all()) + list(Place.objects.all())
data = serializers.serialize('xml', all_objects)

二、反序列化数据

反序列化也相当简单,如下所示:

for obj in serializers.deserialize("xml", data):
do_something_with(obj)

其中的data是我们以前序列化后生成的数据(一个字符串或者数据流)。deserialize()方法返回的是一个迭代器,通过for循环,拿到它内部的每个元素。

在这里有区别的是,deserialize返回的迭代器对象不是简单的Django模型的对象。而是特殊的DeserializedObject实例。调用DeserializedObject.save()方法可以将对象保存到数据库。

PS:如果序列化数据中的pk属性不存在或为null,则新实例将保存到数据库。

将DeserializedObject保存到数据库,可以如下操作:

for deserialized_object in serializers.deserialize("xml", data):
if object_should_be_saved(deserialized_object):
deserialized_object.save()

在这么做之前,你必须保证你的序列化数据是合乎你本地ORM模型属性的,否则保存的过程中会出现各种让你挠头的错误,这是很显然的。

三、可序列化的格式

Djanggo支持三种序列化格式,其中的一些可能需要安装第三方库支持:

  • xml
  • json
  • yaml

1. XML

xml格式相当简单:

<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
<object pk="123" model="sessions.session">
<field type="DateTimeField" name="expire_date">2013-01-16T08:16:59.844560+00:00</field>
<!-- ... -->
</object>
</django-objects>

外键字段被序列化成下面的格式:

<object pk="27" model="auth.permission">
<!-- ... -->
<field to="contenttypes.contenttype" name="content_type" rel="ManyToOneRel">9</field>
<!-- ... -->
</object>

多对多字段被序列化成下面的样子:

<object pk="1" model="auth.user">
<!-- ... -->
<field to="auth.permission" name="user_permissions" rel="ManyToManyRel">
<object pk="46"></object>
<object pk="47"></object>
</field>
</object>

2. JSON

序列化成json格式后,看起来是下面的样子:

[
{
"pk": "4b678b301dfd8a4e0dad910de3ae245b",
"model": "sessions.session",
"fields": {
"expire_date": "2013-01-16T08:16:59.844Z",
...
}
}
]

需要注意的是,如果你的ORM模型具有自定义的字段,那么Django给我们提供的序列化工具,就无法正常工作,你必须自己编写相应部分的序列化代码,下面是一个参考的例子:

from django.utils.encoding import force_text
from django.core.serializers.json import DjangoJSONEncoder class LazyEncoder(DjangoJSONEncoder):
def default(self, obj):
if isinstance(obj, YourCustomType):
return force_text(obj)
return super(LazyEncoder, self).default(obj)

上面编写了一个LazyEncoder类,用来实现你的序列化方法,使用下面的方法调用它:

from django.core.serializers import serialize

serialize('json', SomeModel.objects.all(), cls=LazyEncoder)

PS:Python本身不支持序列化到json格式,Django帮我们实现了它自己的模型类序列化为json的方法,但也仅限于此,如果你在Django内写了一个别的自定义类,一样无法序列化为json格式,除非你自己实现,像上面的例子所示。

3. YAML

yaml的格式和json很像,如下所示:

-   fields: {expire_date: !!timestamp '2013-01-16 08:16:59.844560+00:00'}
model: sessions.session
pk: 4b678b301dfd8a4e0dad910de3ae245b

第六章:Django 综合篇 - 9:序列化 serializers的更多相关文章

  1. 第六章Django

    web应用程序 server端建立socket,不断地accept,当收到客户端连接信号之后,服务端向客户端发送数据,将html网页打开,read出来,并发送至客户端,这样客户端就可以浏览到网页的内容 ...

  2. 第六章、ajax方法以及序列化组件

    目录 第六章.ajax方法 一.choice参数介绍 二.MTV与MVC模型 三.ajax方法 四.案例 五.Ajax传json格式的数据 六. AJAX传文件 代码如下 ajax传文件需要注意的事项 ...

  3. 《Django By Example》第六章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:无他,祝大家年会都中奖!) 第六章 ...

  4. [Effective Java]第六章 枚举和注解

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

  6. 第二十二章 Django会话与表单验证

    第二十二章 Django会话与表单验证 第一课 模板回顾 1.基本操作 def func(req): return render(req,'index.html',{'val':[1,2,3...]} ...

  7. Django 缓存、序列化、信号

    一,缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcac ...

  8. Django框架之序列化和上传文件

     一.Django的序列化(对于ajax请求) Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式. 1)django序列化的使用方法 . ...

  9. Django 综合篇

    前面,已经将Django最主要的五大系统介绍完毕,除了这些主要章节,还有很多比较重要的内容,比如开发流程相关.安全.本地化与国际化.常见工具和一些框架核心功能.这些内容的篇幅都不大,但整合起来也是Dj ...

  10. Django的DRF序列化方法

    安装rest_framework -- pip install djangorestframework -- 注册rest_framework序列化 -- Python--json -- 第一版 用v ...

随机推荐

  1. cmd中常用的dos命令

    在电脑中除了我们常见的图形界面之外,图形页面的操作相信都会.那么还有在cmd执行的一些dos命令,可以简单记一下,方便日后复习所用 首先打开cmd窗口,windows+R,然后在对话框输入cmd,进入 ...

  2. ArrayList源码深度剖析,从最基本的扩容原理,到魔幻的迭代器和fast-fail机制,你想要的这都有!!!

    ArrayList源码深度剖析 本篇文章主要跟大家分析一下ArrayList的源代码.阅读本文你首先得对ArrayList有一些基本的了解,至少使用过它.如果你对ArrayList的一些基本使用还不太 ...

  3. java通过注解指定顺序导入excel

    自定义的属性,用来判断顺序的 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; impor ...

  4. 001 Redis 配置

    Redis缓存 1.配置Redis //Redis 配置文件 @Configuration public class RedisConfiguration { @Bean public RedisTe ...

  5. 6 zookeeper实现分布式锁

    zookeeper实现分布式锁 仓库地址:https://gitee.com/J_look/ssm-zookeeper/blob/master/README.md 锁:我们在多线程中接触过,作用就是让 ...

  6. java关键字的概念与特征和标识符的概念和规则

    什么是关键字 比如说邮箱地址 abc@qq.com  123abc@qq.com 这样的只要没有人占用都是和发布的 那么这样呢 hahah@enen@itcast.cn呢 @是电子邮箱当中有特殊含义的 ...

  7. 记vs2019 The view 'xxx' was not found.

    版本:Visual Studio 2019 16.8.2/16.8.4.net core 3.1 1.检测是否是拼写错误2.检查.csproj为文件中是否包含有下面的content remove(这种 ...

  8. js实现两种99乘法表

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 技术分享 | ARM下中标麒麟系统ky10使用Xtrabackup-8.0.25

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 一.需求背景 查询Percona官方手册,Xtrabackup 8.0可以备份M ...

  10. 基于 DolphinScheduler 的数据质量检查实践

    今天给大家带来的分享是基于 Apache DolphinScheduler 的数据质量检查实践,分享的内容主要为以下四点: " 为什么要做数据质量检查? 为什么要基于 DolphinSche ...