django model object序列化实例


Posted in Python onMarch 13, 2020

提到序列化与反序列化,通常会想到 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序列化实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 正则表达式(转义问题)
Dec 15 Python
Python中的赋值、浅拷贝、深拷贝介绍
Mar 09 Python
python实现将汉字转换成汉语拼音的库
May 05 Python
用python做一个搜索引擎(Pylucene)的实例代码
Jul 05 Python
Python3多进程 multiprocessing 模块实例详解
Jun 11 Python
python3爬虫之设计签名小程序
Jun 19 Python
python多线程抽象编程模型详解
Mar 20 Python
python实现大文本文件分割
Jul 22 Python
python实现局域网内实时通信代码
Dec 22 Python
Python Print实现在输出中插入变量的例子
Dec 25 Python
python中有函数重载吗
May 28 Python
Python离线安装openpyxl模块的步骤
Mar 30 Python
浅析python标准库中的glob
Mar 13 #Python
Python3标准库glob文件名模式匹配的问题
Mar 13 #Python
python编写俄罗斯方块
Mar 13 #Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
Mar 13 #Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
Mar 13 #Python
django处理select下拉表单实例(从model到前端到post到form)
Mar 13 #Python
python实现俄罗斯方块游戏(改进版)
Mar 13 #Python
You might like
使用XDebug调试及单元测试覆盖率分析
2011/01/27 PHP
PHP 登录记住密码实现思路
2013/05/07 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
php实例化一个类的具体方法
2019/09/19 PHP
js兼容标准的表格变色效果
2008/06/28 Javascript
父子窗体间传递JSON格式的数据的代码
2010/12/25 Javascript
jquery表单验证需要做些什么
2015/11/17 Javascript
javascript常用经典算法实例详解
2015/11/25 Javascript
JavaScript事件 "事件对象"的注意要点
2016/01/14 Javascript
Atitit.js的键盘按键事件捆绑and事件调度
2016/04/01 Javascript
浅谈js中的延迟执行和定时执行
2016/05/31 Javascript
JavaScript编程中实现对象封装特性的实例讲解
2016/06/24 Javascript
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
2018/09/30 Javascript
如何安装控制器JavaScript生成插件详解
2018/10/21 Javascript
vue前端框架—Mint UI详解(更适用于移动端)
2019/04/30 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
2019/05/16 Javascript
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
Python的numpy库中将矩阵转换为列表等函数的方法
2018/04/04 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
Python Django Cookie 简单用法解析
2019/08/13 Python
Python模块/包/库安装的六种方法及区别
2020/02/24 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
2020/12/14 Python
CSS3动画之利用requestAnimationFrame触发重新播放功能
2019/09/11 HTML / CSS
马来西亚与新加坡长途巴士售票网站:BusOnlineTicket.com
2018/11/05 全球购物
屈臣氏俄罗斯在线商店:Watsons俄罗斯
2020/08/03 全球购物
新闻系毕业生推荐信
2013/11/16 职场文书
给海归自荐信的建议
2013/12/13 职场文书
幼儿园元旦亲子活动方案
2014/02/17 职场文书
法制宣传日活动总结
2014/04/29 职场文书
群教班子对照检查材料
2014/08/26 职场文书
流动人口婚育证明范本
2014/09/26 职场文书
2014年为民办实事工作总结
2014/12/20 职场文书
护士心得体会范文
2016/01/25 职场文书
golang json数组拼接的实例
2021/04/28 Golang
浅谈MySQL next-key lock 加锁范围
2021/06/07 MySQL
OpenCV-Python实现怀旧滤镜与连环画滤镜
2021/06/09 Python