LOADING

Follow me

Django 序列化与反序列化
十二月 5, 2013|IT

Django 序列化与反序列化


  1. Django框架默认集成的是SimpleJson这个Python库,这个库在日常的Json序列化与反序列化已经完全足够,但是一旦涉及到复杂的对象(例如ORM框架上的持久化类)就会有点捉襟见肘。
  2. 下面总结问题和解决方案:(统一使用Django的单元测试来进行测试)
  3. 1.对象的序列化和反序列化。
  4. 首先,SimpleJson完全不支持对象的序列化与反序列化,如果要实现对象的序列化和反序列化,则需要在simplejson的dumps和loads两个方法中去添加参数,分别指明自定义的序列化和反序列化规则(这里的规则泛指方法或者一个类)。只有指定了规则,simplejson才能够知道如何将一个对象序列化为一个字典(dict),反之亦然。因此,解决方法可以使用Django内置的序列化和反序列化工具。这样一来,就可以序列化ORM所查询到的QuerySet对象集合了。
  5. 2.使用Django内置的序列化工具只能够序列化对象集合,想在序列化过程中添加一些额外的需要序列化的信息。
  6. 例如,在网络传输时,不但要传输对象集合,还需要传输一些额外的信息,例如标识结果的字符串result=”success”,这样一来就不能仅仅使用Django内置的序列化工具,而只能使用Python所有的SimpleJson库,而悖论的地方在于SimpleJson不支持序列化对象集合,因此,就需要对SimpleJson的方法进行一些加工。这里就是使用simplejson.dumps()方法所有的cls这个参数来指定自定义自己的序列化处理类
  7. 3.序列化或反序列化单个对象
  8. Django的序列化工具只支持对象集合,因此需要做一些取巧的手段来完成序列化或者反序列化单个对象。
  9. 下面贴出解决方案的代码,详细的注释在代码中:
  10. 复制代码
  11.  1from
    django.utils
    import simplejson
  12.  2from
    django.db
    import models
  13.  3from
    django.core.serializers
    import serialize,deserialize
  14.  4from
    django.db.models.query
    import QuerySet
  15.  5from
    django.test
    import TestCase
  16.  6
  17.  7class
    MyEncoder(simplejson.JSONEncoder):
  18.  8“””
    继承自simplejson的编码基类,用于处理复杂类型的编码
  19.  9“””
  20. 10def
    default(self,obj):
  21. 11if
    isinstance(obj,QuerySet):
  22. 12“””
    Queryset实例
  23. 13直接使用Django内置的序列化工具进行序列化
  24. 14但是如果直接返回serialize(‘json’,obj)
  25. 15则在simplejson序列化时会被从当成字符串处理
  26. 16则会多出前后的双引号
  27. 17因此这里先获得序列化后的对象
  28. 18然后再用simplejson反序列化一次
  29. 19得到一个标准的字典(dict)对象
  30. 20“””
  31. 21return
    simplejson.loads(serialize(
    json,obj))
  32. 22if
    isinstance(obj,models.Model):
  33. 23“””
  34. 24如果传入的是单个对象,区别于QuerySet的就是
  35. 25Django不支持序列化单个对象
  36. 26因此,首先用单个对象来构造一个只有一个对象的数组
  37. 27这是就可以看做是QuerySet对象
  38. 28然后此时再用Django来进行序列化
  39. 29就如同处理QuerySet一样
  40. 30但是由于序列化QuerySet会被'[]’所包围
  41. 31因此使用string[1:-1]来去除
  42. 32由于序列化QuerySet而带入的'[]’
  43. 33“””
  44. 34return
    simplejson.loads(serialize(
    json,[obj])[1:-1])
  45. 35if
    hasattr(obj,
    isoformat):
  46. 36#处理日期类型
  47. 37return
    obj.isoformat()
  48. 38return
    simplejson.JSONEncoder.default(self,obj)
  49. 39
  50. 40def
    jsonBack(json):
  51. 41“””
    进行Json字符串的反序列化
  52. 42一般来说,从网络得回的POST(或者GET)
  53. 43参数中所包含json数据
  54. 44例如,用POST传过来的参数中有一个key
    value键值对为
  55. 45request.POST[‘update’]
  56. 46= “[{pk:1,name:’changename’},{pk:2,name:’changename2′}]”
  57. 47要将这个value进行反序列化
  58. 48则可以使用Django内置的序列化与反序列化
  59. 49但是问题在于
  60. 50传回的有可能是代表单个对象的json字符串
  61. 51如:
  62. 52request.POST[‘update’]
    = “{pk:1,name:’changename’}”
  63. 53这是,由于Django无法处理单个对象
  64. 54因此要做适当的处理
  65. 55将其模拟成一个数组,也就是用'[]’进行包围
  66. 56再进行反序列化
  67. 57“””
  68. 58if
    json[0] ==
    [:
  69. 59return
    deserialize(
    json,json)
  70. 60else:
  71. 61return
    deserialize(
    json,[
    + json +
    ])
  72. 62
  73. 63def
    getJson(**
    args):
  74. 64“””
    使用MyEncoder这个自定义的规则类来序列化对象
  75. 65“””
  76. 66 result = dict(args)
  77. 67return
    simplejson.dumps(result,cls=MyEncoder)
  78. 复制代码
  79.  
  80.  
  81.  在上面的例子中,自定义了一个序列化规则类MyEncoder,用来处理集合或者集合对象,然后实现了一个可变参数的工具方法getJson,用于传入多个参数,并将其一同序列化。另外还有一个反序列化对象的方法jsonBack,接受一个代表对象或者对象集合的json而返回一个对象集合。这样一来就可以很好的使用配合SimpleJson和Django来完成序列化工作了。


版权声明:本文为博主原创文章,未经博主允许不得转载。

no comments
Share

发表评论