zoukankan      html  css  js  c++  java
  • Django框架中使用json格式序列化与反序列化QuerySet和Model

    转自:http://cyfloel0516.sinaapp.com/?tag=django

    Django框架默认集成的是SimpleJson这个Python库,这个库在日常的Json序列化与反序列化已经完全足够,但是一旦涉及到复杂的对象(例如ORM框架上的持久化类)就会有点捉襟见肘。

    下面总结问题和解决方案:(统一使用Django的单元测试来进行测试)

    1.对象的序列化和反序列化。

    首先,SimpleJson完全不支持对象的序列化与反序列化,如果要实现对象的序列化和反序列化,则需要在simplejson的dumps和loads两个方法中去添加参数,分别指明自定义的序列化和反序列化规则(这里的规则泛指方法或者一个类)。只有指定了规则,simplejson才能够知道如何将一个对象序列化为一个字典(dict),反之亦然。因此,解决方法可以使用Django内置的序列化和反序列化工具。这样一来,就可以序列化ORM所查询到的QuerySet对象集合了。

    2.使用Django内置的序列化工具只能够序列化对象集合,想在序列化过程中添加一些额外的需要序列化的信息。

    例如,在网络传输时,不但要传输对象集合,还需要传输一些额外的信息,例如标识结果的字符串result=”success”,这样一来就不能仅仅使用Django内置的序列化工具,而只能使用Python所有的SimpleJson库,而悖论的地方在于SimpleJson不支持序列化对象集合,因此,就需要对SimpleJson的方法进行一些加工。这里就是使用simplejson.dumps()方法所有的cls这个参数来指定自定义自己的序列化处理类

    3.序列化或反序列化单个对象

    Django的序列化工具只支持对象集合,因此需要做一些取巧的手段来完成序列化或者反序列化单个对象。

    下面贴出解决方案的代码,详细的注释在代码中:

     1 from django.utils import simplejson
     2 from django.db import models
     3 from django.core.serializers import serialize,deserialize
     4 from django.db.models.query import QuerySet
     5 from django.test import TestCase
     6 
     7 class MyEncoder(simplejson.JSONEncoder):
     8     """ 继承自simplejson的编码基类,用于处理复杂类型的编码
     9     """
    10     def default(self,obj):
    11             if isinstance(obj,QuerySet):
    12                 """ Queryset实例
    13                 直接使用Django内置的序列化工具进行序列化
    14                 但是如果直接返回serialize('json',obj)
    15                 则在simplejson序列化时会被从当成字符串处理
    16                 则会多出前后的双引号
    17                 因此这里先获得序列化后的对象
    18                 然后再用simplejson反序列化一次
    19                 得到一个标准的字典(dict)对象
    20                 """
    21                 return simplejson.loads(serialize('json',obj))
    22             if isinstance(obj,models.Model):
    23                 """
    24                 如果传入的是单个对象,区别于QuerySet的就是
    25                 Django不支持序列化单个对象
    26                 因此,首先用单个对象来构造一个只有一个对象的数组
    27                 这是就可以看做是QuerySet对象
    28                 然后此时再用Django来进行序列化
    29                 就如同处理QuerySet一样
    30                 但是由于序列化QuerySet会被'[]'所包围
    31                 因此使用string[1:-1]来去除
    32                 由于序列化QuerySet而带入的'[]'
    33                 """
    34                 return simplejson.loads(serialize('json',[obj])[1:-1])
    35             if hasattr(obj, 'isoformat'):
    36                 #处理日期类型
    37                 return obj.isoformat()
    38             return simplejson.JSONEncoder.default(self,obj)
    39 
    40 def jsonBack(json):
    41     """    进行Json字符串的反序列化
    42         一般来说,从网络得回的POST(或者GET)
    43         参数中所包含json数据
    44         例如,用POST传过来的参数中有一个key value键值对为
    45         request.POST['update']
    46         = "[{pk:1,name:'changename'},{pk:2,name:'changename2'}]"
    47         要将这个value进行反序列化
    48         则可以使用Django内置的序列化与反序列化
    49         但是问题在于
    50         传回的有可能是代表单个对象的json字符串
    51         如:
    52         request.POST['update'] = "{pk:1,name:'changename'}"
    53         这是,由于Django无法处理单个对象
    54         因此要做适当的处理
    55         将其模拟成一个数组,也就是用'[]'进行包围
    56         再进行反序列化
    57     """
    58     if json[0] == '[':
    59         return deserialize('json',json)
    60     else:
    61         return deserialize('json','[' + json +']')
    62 
    63 def getJson(**args):
    64     """    使用MyEncoder这个自定义的规则类来序列化对象
    65     """
    66     result = dict(args)
    67     return simplejson.dumps(result,cls=MyEncoder)
     

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

  • 相关阅读:
    前端神器avalonJS入门(一)
    emmet的使用
    VS2015中SharedProject与可移植类库(PCL)项目
    Map工具系列-08-map控件查看器
    Map工具系列-07-TFS变更集提取工具
    Map工具系列-06-销售营改增历史数据处理工具
    2018.04.02 matplotlib 图名,图例,轴标签,轴边界,轴刻度,轴刻度标签
    2018.03.30 abap屏幕标签保存之前执行过的状态
    2018.03.29 python-matplotlib 图表生成
    2018.03.29 python-pandas 数据读取
  • 原文地址:https://www.cnblogs.com/waniu/p/2538669.html
Copyright © 2011-2022 走看看