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序列化实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Python序列化pickle模块使用详解

    用于序列化的两个模块 json:用于字符串和Python数据类型间进行转换 pickle: 用于python特有的类型和python的数据类型间进行转换 json提供四个功能:dumps,dump,loads,load pickle提供四个功能:dumps,dump,loads,load pickle可以存储什么类型的数据呢? 所有python支持的原生类型:布尔值,整数,浮点数,复数,字符串,字节,None. 由任何原生类型组成的列表,元组,字典和集合. 函数,类,类的实例 pickle模块中

  • Python 之 Json序列化嵌套类方式

    想要用python自已手动序列化嵌套类,就要明白两个问题: 1.Json是什么? 2.Json支持什么类型? 答案显而易见 Json就是嵌套对象 Json在python中支持列表,字典(当然也支持int,string.....,不过说这个也没多大必要) 很好,等等,列表,字典?我们在python中学过列表,字典,字典列表,列表字典,字典字典,那,我们可不可以把类对象转化为这些呢? 我可以很确定的告诉你,可以,并且,嵌套类都可以!!! 下面就来实战: from flask import Flask

  • django model object序列化实例

    提到序列化与反序列化,通常会想到 json ,xml .在J2EE的开发中,这是很常用的技术,比如一个java class与xml之间的序列化与反序列化,我们可以通过 xstream来实现,如果是与json之间的转换,我们可以通过 gson.jar或者jsonlib.jar 来实现.方法很多,也是常见的方法. 但在python 中,我们常用的是json 的序列化,python2.7 已经包含了json package,这个也是从simplejson 基础上改变而来.这个json 包主要提供了du

  • django rest framework serializers序列化实例

    serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用: - 将queryset与model实例等进行序列化,转化成json格式,返回给用户(api接口). - 将post与patch/put的上来的数据进行验证. - 对post与patch/put数据进行处理. 实现序列化二个类:Serializer与ModelSerializer 比较 ModelSerializer(Serializer) 即 ModelSerializer继承了Se

  • 在Django model中设置多个字段联合唯一约束的实例

    使用Django中遇到这样一个需求,对一个表的几个字段做 联合唯一索引,例如学生表中 姓名和班级 2个字段在一起表示一个唯一记录. Django中model部分的写法, 参见 unique-together 部分文档. class MyModel(models.Model): field1 = models.CharField(max_length=50) field2 = models.CharField(max_length=50) class Meta: unique_together =

  • django model通过字典更新数据实例

    example: models中的表 # models class UserInfo(models.Model): id = models.BigAutoField(primary_key=True) user_name = models.CharField(max_length=100, verbose_name='用户名') cellphone = models.CharField(max_length=100, blank=False, null=True, verbose_name='手

  • django使用graphql的实例

    一.开发环境 1.python3.6 2.django2.0 3.window10 二.项目搭建 1.创建一个虚拟空间mkvirtualenv 空间名 2.创建一个django项目 3.安装graphql的依赖包 pip install graphene-django 4.创建一个组件blog 5.把组件blog及graphene_django注入到app中 6.在settings.py中配置mysql数据库连接 三.书写blog的内容 1.在models.py中写上数据模型 from djan

  • Django数据库操作的实例(增删改查)

    创建数据库中的一个表 class Business(models.Model): #自动创建ID列 caption = models.CharField(max_length=32) code = models.CharField(max_length=32) 1.增加 方法一 models.Business.objects.create(caption='市场部',code='123') 方法二 obj = models.UserInfo(caption='市场部',code='123') o

  • Django model select的多种用法详解

    <Django model update的各种用法介绍>文章介绍了Django model的各种update操作,这篇文章就是她的姊妹篇,详细介绍Django model select的用法,配以对应MySQL的查询语句,理解起来更轻松. 基本操作 # 获取所有数据,对应SQL:select * from User User.objects.all() # 匹配,对应SQL:select * from User where name = '运维咖啡吧' User.objects.filter(

  • Django REST Framework序列化外键获取外键的值方法

    需求:序列化外键,获取外键的除id之外的值 使用Django REST Framework虽然开发接口快速,但是如果想要获取到除外键id值之外的外键信息,直接继承serializers.ModelSerializer类,然后在fields中指定返回的字段是获取不到外键的其他值的,比如我现在需要外键的name属性值,下面就给大家介绍两种方法通过序列化外键来获取我们想要的外键的值. 这里有两个Model:问卷(Questionnaire):问题(Question).一张问卷中包含多个问题,问题通过外

  • Django框架中序列化和反序列化的例子

    1.序列化 DRF的核心 就是 前后端分离的核心 前后端分离开发的核心: 将模型转换为json 称之为 序列化 将json转换为模型 称之为 反序列化 1.序列化器的字段 Serializer 序列化器 为了得到模型里的字段,序列化器中的字段应与模型类中的字段名一致 ''' serializers.py ''' class BookInfoSerializer(serializers.Serializer): # read_only=True 只能读 不能修改 id = serializers.

  • 用sqlalchemy构建Django连接池的实例

    都知道django每次请求都会连接数据库和释放数据库连接.Django为每个请求使用新的数据库连接.一开始这个方法行得通.然而随着服务器上的负载的增加,创建/销毁连接数据库开始花大量的时间.要避免这个,你可以使用数据库连接池,这里使用SQLAlchemy的连接池.使Django持久化数据库连接. 但这种方法会改变django的代码.对框架有侵入 方法 1 实现方法如下: 把django/db/backends/mysql文件夹全部拷贝出来,放在项目的一个libs/mysql下面,然后修改base

随机推荐