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來完成序列化工作了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM