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序列化 serializers的更多相关文章

  1. django rest_framework Serializers 序列化组件

    为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿 ...

  2. 第六章:Django 综合篇 - 9:序列化 serializers

    Django的序列化工具让你可以将Django的模型'翻译'成其它格式的数据.通常情况下,这种其它格式的数据是基于文本的,并且用于数据交换\传输过程. 一.序列化数据 Django为我们提供了一个强大 ...

  3. 通过ajax GET方式查询数据,Django序列化objects

    点击“查找2”按钮,通过ajax GET方式进行查询数据,这样页面不需要整体刷新,之后清空tbody数据,将查询结果重新附加到tbody 前端html: <div class="box ...

  4. Django序列化

    一.Django序列化    1.序列化应用场景     1.关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,由于httpresponse只能返回字符串或者是字节,而从数据库 ...

  5. Django序列化&django REST framework

    第一章.Django序列化操作 1.django的view实现商品列表页(基于View类) # 通过json来序列化,但手写字典key代码量较大,容易出错:还有遇到时间,图片序列化会报错 from g ...

  6. Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)

    12.4 Cookie和Session 12.41 cookie Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务 ...

  7. Django Rest Framework源码剖析(六)-----序列化(serializers)

    一.简介 django rest framework 中的序列化组件,可以说是其核心组件,也是我们平时使用最多的组件,它不仅仅有序列化功能,更提供了数据验证的功能(与django中的form类似). ...

  8. Django序列化组件Serializers详解

    本文主要系统性的讲解django rest framwork 序列化组件的使用,基本看完可以解决工作中序列化90%的问题,写作参考官方文档https://www.django-rest-framewo ...

  9. Django 序列化

    序列化 背景 对于Django 的queryset 对象在传递给 前端的时候,前端是无法识别的 因此需要存在一个转换过程将 queryset 对象转换成 字符串前端才可以识别 演示 QuerySet ...

随机推荐

  1. Java用Gson遍历json所有节点

    <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</ar ...

  2. 数据库的增、删、改、查 (CURD)

    增改查删可以用CURD来表示  增加:create  修改:update   查找:read      删除:delete 增加create :  insert +表名+values+(信息): in ...

  3. selenium 模拟手机

    import time from selenium import webdriver mobileEmulation = {'deviceName': 'Galaxy S5'} options = w ...

  4. 利用Python实现多线程聊天功能

    #-*- coding:utf-8 -*- from threading import Thread from socket import * #1.实现接收消息 def recvDate(): wh ...

  5. mysql引擎和事务

    对于应用程序和用户来说,同样一张表的数据无论用什么引擎来存储,看到的数据都是一样的,只是不同的引擎在功能.占用空间大小.读取性能等方面可能有所差别. mysql最常用的存储引擎为Innodb.MyIS ...

  6. bzoj1088 P2327 [SCOI2005]扫雷

    P2327 [SCOI2005]扫雷 emmmmm.....这题真可以用状压写 因为每个数字只对3个格子有影响,相当于只有2^3=8种状态,所以可以用状压瞎搞 我们用8个数字代表二进制下的8种状态 0 ...

  7. 搭建一个简单的svn服务器(旧)

    cenos 6.5,svnserver 1.6.11 默认可能已经安装,没有的话就: yum install svn -ysvnserver --version 创建一个svn仓库: svnadmin ...

  8. Android - Resource 之 Layout 小结

    Layout定义了一个Activity的UI框架,或者是一个UI的组件. 文法如下: ?xml version="1.0" encoding="utf-8"?& ...

  9. python简说(八)random

    import randomprint(random.randint(1,23))#随机整数l=[1,2,3,4]s='abcdefeg'print(random.choice(s))#随机选择一个元素 ...

  10. [c/c++] programming之路(8)、汇编、求模、自增自减

    一.插入汇编 #include<stdio.h> void main(){ ; num=num+; //插入汇编语言 _asm{ mov eax,num;//eax是一个存储器,将num的 ...