django model object序列化实例

提到序列化与反序列化,通常会想到 json ,xml .在J2EE的开发中,这是很常用的技术,比如一个java class与xml之间的序列化与反序列化,我们可以通过 xstream来实现,如果是与json之间的转换,我们可以通过 gson.jar或者jsonlib.jar 来实现。方法很多,也是常见的方法。

但在python 中,我们常用的是json 的序列化,python2.7 已经包含了json package,这个也是从simplejson 基础上改变而来。这个json 包主要提供了dump,load 来实现dict 与 字符串之间的序列化与反序列化,这很方便的可以完成,可以参考这篇文章python json。但现在的问题是,这个json包不能序列化 django 的models 里面的对象的实例。

经过分析,网络搜索,发现有如下解决方案.

利用 from django.core import serializers 的方法实现

from django.core import serializers

data = serializers.serialize("json", SomeModel.objects.all())

data1 = serializers.serialize("json", SomeModel.objects.filter(myfield1=myvalue))

上面两个是没有问题的,因为序列化的对象是 Queryset, 因此是成功的。但如果是用SomeModel.objects.get(id=myid) 得到一个具体的实例的时候,问题就来了

data = serializers.serialize("json", SomeModel.objects.get(id=myid))

肯定会出现如下错误:

for obj in queryset: TypeError: 'SomeModel' object is not iterable

一看错误就知道,因为 SomeModel.objects.get(id=myid) 返回的是一个具体的实例,而不是一个集合对象,因此是不可以 iterable 的。所以报错。

从上面的分析可以看出 django的 serializers 只支持 queryset,而不支持model的实例,那么怎么实现呢?

1.我们自己把这个单个对象模拟成一个集合,然后去掉前后的"[""]"符号,就可以了。

from django.utils import simplejson

from django.db import models

from django.core.serializers import serialize,deserialize

from django.db.models.query import QuerySet

from django.test import TestCase

class MyEncoder(simplejson.JSONEncoder):

""" 继承自simplejson的编码基类,用于处理复杂类型的编码

"""

def default(self,obj):

if isinstance(obj,QuerySet):

""" Queryset实例

直接使用Django内置的序列化工具进行序列化

但是如果直接返回serialize('json',obj)

则在simplejson序列化时会被从当成字符串处理

则会多出前后的双引号

因此这里先获得序列化后的对象

然后再用simplejson反序列化一次

得到一个标准的字典(dict)对象

"""

return simplejson.loads(serialize('json',obj))

if isinstance(obj,models.Model):

"""

如果传入的是单个对象,区别于QuerySet的就是

Django不支持序列化单个对象

因此,首先用单个对象来构造一个只有一个对象的数组

这是就可以看做是QuerySet对象

然后此时再用Django来进行序列化

就如同处理QuerySet一样

但是由于序列化QuerySet会被'[]'所包围

因此使用string[1:-1]来去除

由于序列化QuerySet而带入的'[]'

"""

return simplejson.loads(serialize('json',[obj])[1:-1])

if hasattr(obj, 'isoformat'):

#处理日期类型

return obj.isoformat()

return simplejson.JSONEncoder.default(self,obj)

def jsonBack(json):

""" 进行Json字符串的反序列化

一般来说,从网络得回的POST(或者GET)

参数中所包含json数据

例如,用POST传过来的参数中有一个key value键值对为

request.POST['update']

= "[{pk:1,name:'changename'},{pk:2,name:'changename2'}]"

要将这个value进行反序列化

则可以使用Django内置的序列化与反序列化

但是问题在于

传回的有可能是代表单个对象的json字符串

如:

request.POST['update'] = "{pk:1,name:'changename'}"

这是,由于Django无法处理单个对象

因此要做适当的处理

将其模拟成一个数组,也就是用'[]'进行包围

再进行反序列化

"""

if json[0] == '[':

return deserialize('json',json)

else:

return deserialize('json','[' + json +']')

def getJson(**args):

""" 使用MyEncoder这个自定义的规则类来序列化对象

"""

result = dict(args)

return simplejson.dumps(result,cls=MyEncoder)

在上面的例子中,自定义了一个序列化规则类MyEncoder,用来处理集合或者集合对象,然后实现了一个可变参数的工具方法getJson,用于传入多个参数,并将其一同序列化。另外还有一个反序列化对象的方法jsonBack,接受一个代表对象或者对象集合的json而返回一个对象集合。这样一来就可以很好的使用配合SimpleJson和Django来完成序列化工作了

2.直接利用python 2.7 提供的json包,或者用simplejson都可以

首先,你需要在django model的定义中增加一个方法toJSON,利用了django model 能访问 _meta.fields 得到相关属性而得到,例子如下

class Category(models.Model):

autoid = models.AutoField(primary_key=True)

email=models.CharField(max_length=150,blank=False)

comtype=models.CharField(max_length=20,blank=False)

catname=models.CharField(max_length=150,blank=False)

def __unicode__(self):

return '%s' % (self.catname)

def toJSON(self):

import json

return json.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))

现在用django查出数据,并转换成json

row=models.Category.objects.get(autoid=23) print row.toJSON()

你会发现,成功转换了。当然,这个toJSON方法,如果要求可读性比较好的话,可以这样写

def toJSON(self):

fields = []

for field in self._meta.fields:

fields.append(field.name)

d = {}

for attr in fields:

d[attr] = getattr(self, attr)

import json

return json.dumps(d)

补充知识:django模型类序列化器 ModelSerializer

1. 定义

比如我们创建一个BookInfoSerializer

class BookInfoSerializer(serializers.ModelSerializer):

"""图书数据序列化器"""

class Meta:

model = BookInfo

fields = '__all__'

model 指明参照哪个模型类

fields 指明为模型类的哪些字段生成

2. 指定字段

1) 使用fields来明确字段,__all__表名包含所有字段,也可以写明具体哪些字段,如

class BookInfoSerializer(serializers.ModelSerializer):

"""图书数据序列化器"""

class Meta:

model = BookInfo

fields = ('id', 'btitle', 'bpub_date')

2) 使用exclude可以明确排除掉哪些字段

class BookInfoSerializer(serializers.ModelSerializer):

"""图书数据序列化器"""

class Meta:

model = BookInfo

exclude = ('image',)

3) 默认ModelSerializer使用主键作为关联字段,但是我们可以使用depth来简单的生成嵌套表示,depth应该是整数,表明嵌套的层级数量。如:

class HeroInfoSerializer2(serializers.ModelSerializer):

class Meta:

model = HeroInfo

fields = '__all__'

depth = 1

4) 指明只读字段

可以通过read_only_fields指明只读字段,即仅用于序列化输出的字段

3. 添加额外参数

我们可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数

class BookInfoSerializer(serializers.ModelSerializer):

"""图书数据序列化器"""

class Meta:

model = BookInfo

fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')

extra_kwargs = {

'bread': {'min_value': 0, 'required': True},

'bcomment': {'min_value': 0, 'required': True},

}

以上这篇django model object序列化实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 django model object序列化实例 的全部内容, 来源链接: utcz.com/z/339179.html

回到顶部