json及其在django中的应用

1、JSON

還不知道 JSON 是什麼嘛?本篇教學會帶您瞭解 JSON 在網站上的應用,以及運作流程跟使用PHP 和 JavaScript 來處理 JSON。假如您現在的工作就是網站設計師,相信一定聽過 JSON,但是什麼是 JSON,它能夠做什麼,及您能透過它在網站上做到哪些事情呢? 透過本篇介紹您可以瞭解基本的 JSON,底下會列出本篇會提到的重點:

  • 什麼是 JSON
  • JSON 應用在哪些地方
  • 如何建立 JSON 字串
  • 一個簡單的 JSON 範例
  • JSON vs XML
  • 如何透過 PHP 及 JavaScript 使用 JSON

什麼是 JSON

JSON 是個以純文字為基底去儲存和傳送簡單結構資料,你可以透過特定的格式去儲存任何資料(字串,數字,陣列,物件),也可以透過物件或陣列來傳送較複雜的資料。一旦建立了您的 JSON 資料,就可以非常簡單的跟其他程式溝通或交換資料,因為 JSON 就只是純文字個格式。 JSON 的優點如下:
  • 相容性高
  • 格式容易瞭解,閱讀及修改方便
  • 支援許多資料格式 (number,string,booleans,nulls,array,associative array)
  • 許多程式都支援函式庫讀取或修改 JSON 資料

JSON 應用在哪些地方

JSON 最常用用在 Web 網頁程式從 Server 端傳送資料給 browser,典型範例就是透過 AJAX 方式交換 JSON 資料,底下簡單舉個範例 1. 使用者點選了線上產品縮圖 2. JavaScript 透過 AJAX 方式將產品 ID 傳送給伺服器端 3. 伺服器端收到 ID,將產品資料 (ex 價格,描述) 編碼成 JSON 資料,並且回傳給瀏覽器 4. JavaScript 收到 JSON 資料,將其解碼 (decode) 並且將資料顯示在網頁上 您也可以透過網頁將 JSON 資料傳到伺服器端,這都是可以的,把 POST 或 GET 資訊編碼成 JSON 格式即可,如果有在使用 jQuery,它提供了兩個函式處理 JSON,分別是  getJSON  跟 parseJSON

如何建立 JSON 字串

可以透過底下規則來建立 JSON 字串 1. JSON 字串可以包含陣列 Array 資料或者是物件 Object 資料 2. 陣列可以用  [ ]  來寫入資料 3. 物件可以用  { }  來寫入資料 4. name / value 是成對的,中間透過 ( : ) 來區隔 物件或陣列的 value 值可以如下: 1. 數字 (整數或浮點數) 2. 字串 (請用 “” 括號) 3. 布林函數 (boolean) (true 或 false) 4. 陣列 (請用 [ ] ) 5. 物件 (請用 { } ) 6. NULL

一個簡單的 JSON 範例

{
  "orderID": 12345,
  "shopperName": "John Smith",
  "shopperEmail": "johnsmith@example.com",
  "contents": [
    {
      "productID": 34,
      "productName": "SuperWidget",
      "quantity": 1
    },
    {
      "productID": 56,
      "productName": "WonderWidget",
      "quantity": 3
    }
  ],
  "orderCompleted": true
}
由上面例子我們可以發現 contents 陣列裡面又包含物件,透過上面例子,我們寫成 JavaScript 如下:
<script type="text/javascript">
var cart = {
  "orderID": 12345,
  "shopperName": "John Smith",
  "shopperEmail": "johnsmith@example.com",
  "contents": [
    {
      "productID": 34,
      "productName": "SuperWidget",
      "quantity": 1
    },
    {
      "productID": 56,
      "productName": "WonderWidget",
      "quantity": 3
    }
  ],
  "orderCompleted": true
};
</script>

JSON vs XML

在許多方面,你可以想像 JSON 來替代 XML,在過去 Web Application 開發 AJAX 都是透過 XML 來交換資料,但是你可以發現近幾年來 JSON 已經漸漸取代 XML 格式了,為什麼會變成這樣呢?因為 JSON 格式容易閱讀且好修改,許多程式語言分別開發了函式庫來處理 JSON 資料,我們可以把上面的 JSON 資料改寫成 XML 如下:
<object>
  <property>
    <key>orderID</key>
    <number>12345</number>
  </property>
  <property>
    <key>shopperName</key>
    <string>John Smith</string>
  </property>
  <property>
    <key>shopperEmail</key>
    <string>johnsmith@example.com</string>
  </property>
  <property>
    <key>contents</key>
    <array>
      <object>
        <property>
          <key>productID</key>
          <number>34</number>
        </property>
        <property>
          <key>productName</key>
          <string>SuperWidget</string>
        </property>
        <property>
          <key>quantity</key>
          <number>1</number>
        </property>        
      </object>
      <object>
        <property>
          <key>productID</key>
          <number>56</number>
        </property>
        <property>
          <key>productName</key>
          <string>WonderWidget</string>
        </property>
        <property>
          <key>quantity</key>
          <number>3</number>
        </property> 
      </object>
    </array>
  </property>
  <property>
    <key>orderCompleted</key>
    <boolean>true</boolean>
  </property>  
</object>
 大家有沒有發現 XML 的資料量遠大於 JSON 資料量,這也是 JSON 優於 XML 的原因之一

如何利用 JavaScript 來處理 JSON 資料

直接看例子比較快: 
<script type="text/javascript">

var cart = {
  "orderID": 12345,
  "shopperName": "John Smith",
  "shopperEmail": "johnsmith@example.com",
  "contents": [
    {
      "productID": 34,
      "productName": "SuperWidget",
      "quantity": 1
    },
    {
      "productID": 56,
      "productName": "WonderWidget",
      "quantity": 3
    }
  ],
  "orderCompleted": true
};

alert ( JSON.stringify( cart ) ); 

</script>
 透過 JSON.stringify 來轉換資料,產生結果如下
{"orderID":12345,"shopperName":"John Smith","shopperEmail":"johnsmith@example.com",
"contents":[{"productID":34,"productName":"SuperWidget","quantity":1},
{"productID":56,"productName":"WonderWidget","quantity":3}],
"orderCompleted":true}
如何將 JSON 字串傳入 JavaScript 變數
<script type="text/javascript">

var jsonString = '                          \
{                                           \
  "orderID": 12345,                         \
  "shopperName": "John Smith",              \
  "shopperEmail": "johnsmith@example.com",  \
  "contents": [                             \
    {                                       \
      "productID": 34,                      \
      "productName": "SuperWidget",         \
      "quantity": 1                         \
    },                                      \
    {                                       \
      "productID": 56,                      \
      "productName": "WonderWidget",        \
      "quantity": 3                         \
    }                                       \
  ],                                        \
  "orderCompleted": true                    \
}                                           \
';

var cart = JSON.parse ( jsonString );

alert ( cart.shopperEmail );
alert ( cart.contents[1].productName );

</script>
 結果如下 cart.shopperEmail 輸出 johnsmith@example.com cart.contents[1].productName 輸出 WonderWidget

转自: http://blog.wu-boy.com/2011/04/%E4%BD%A0%E4%B8%8D%E5%8F%AF%E4%B8%8D%E7%9F%A5%E7%9A%84-json-%E5%9F%BA%E6%9C%AC%E4%BB%8B%E7%B4%B9/


2、json在django中的使用

if request.method=='POST':
        rst={}
        raw_data=json.loads(request.body);
        id=raw_data['orderID']
        prds=raw_data['product_list']
        sum=0
        for prd in prds:
            sum+=prd['price']
        rst['orderID']=id
        rst['sum']=sum
        rspn=json.dumps(rst)
        return HttpResponse(rspn)

json可直接用来传递数组和字典,用户也可自定义传输的数据类型。

Json概述以及python对json的相关操作

什么是json:

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构:

“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。 
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。 
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

jso官方说明参见:http://json.org/

Python操作json的标准api库参考:http://docs.python.org/library/json.html

对简单数据类型的encoding 和 decoding:

使用简单的json.dumps方法对简单数据类型进行编码,例如:

1
2
3
4
5
6
import  json
 
obj =  [[ 1 , 2 , 3 ], 123 , 123.123 , 'abc' ,{ 'key1' :( 1 , 2 , 3 ), 'key2' :( 4 , 5 , 6 )}]
encodedjson =  json.dumps(obj)
print  repr (obj)
print  encodedjson

输出:

[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}] 
[[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]

通过输出的结果可以看出,简单类型通过encode之后跟其原始的repr()输出结果非常相似,但是有些数据类型进行了改变,例如上例中的元组则转换为了列表。在json的编码过程中,会存在从python原始类型向json类型的转化过程,具体的转化对照如下:

image

json.dumps()方法返回了一个str对象encodedjson,我们接下来在对encodedjson进行decode,得到原始数据,需要使用的json.loads()函数:

1
2
3
4
decodejson =  json.loads(encodedjson)
print  type (decodejson)
print  decodejson[ 4 ][ 'key1' ]
print  decodejson

输出:

<type 'list'> 
[1, 2, 3]

[[1, 2, 3], 123, 123.123, u'abc', {u'key2': [4, 5, 6], u'key1': [1, 2, 3]}]

loads方法返回了原始的对象,但是仍然发生了一些数据类型的转化。比如,上例中‘abc’转化为了unicode类型。从json到python的类型转化对照如下:

image

json.dumps方法提供了很多好用的参数可供选择,比较常用的有sort_keys(对dict对象进行排序,我们知道默认dict是无序存放的),separators,indent等参数。

排序功能使得存储的数据更加有利于观察,也使得对json输出的对象进行比较,例如:

1
2
3
4
5
6
7
8
9
10
data1 =  { 'b' : 789 , 'c' : 456 , 'a' : 123 }
data2 =  { 'a' : 123 , 'b' : 789 , 'c' : 456 }
d1 =  json.dumps(data1,sort_keys = True )
d2 =  json.dumps(data2)
d3 =  json.dumps(data2,sort_keys = True )
print  d1
print  d2
print  d3
print  d1 = = d2
print  d1 = = d3

输出:

{"a": 123, "b": 789, "c": 456} 
{"a": 123, "c": 456, "b": 789} 
{"a": 123, "b": 789, "c": 456} 
False 
True

上例中,本来data1和data2数据应该是一样的,但是由于dict存储的无序特性,造成两者无法比较。因此两者可以通过排序后的结果进行存储就避免了数据比较不一致的情况发生,但是排序后再进行存储,系统必定要多做一些事情,也一定会因此造成一定的性能消耗,所以适当排序是很重要的。

indent参数是缩进的意思,它可以使得数据存储的格式变得更加优雅。

1
2
3
data1 =  { 'b' : 789 , 'c' : 456 , 'a' : 123 }
d1 =  json.dumps(data1,sort_keys = True ,indent = 4 )
print  d1

输出:


    "a": 123, 
    "b": 789, 
    "c": 456 
}

输出的数据被格式化之后,变得可读性更强,但是却是通过增加一些冗余的空白格来进行填充的。json主要是作为一种数据通信的格式存在的,而网络通信是很在乎数据的大小的,无用的空格会占据很多通信带宽,所以适当时候也要对数据进行压缩。separator参数可以起到这样的作用,该参数传递是一个元组,包含分割对象的字符串。

1
2
3
4
5
print  'DATA:' , repr (data)
print  'repr(data)             :' , len ( repr (data))
print  'dumps(data)            :' , len (json.dumps(data))
print  'dumps(data, indent=2)  :' , len (json.dumps(data, indent = 4 ))
print  'dumps(data, separators):' , len (json.dumps(data, separators = ( ',' , ':' )))

输出:

DATA: {'a': 123, 'c': 456, 'b': 789} 
repr(data)             : 30 
dumps(data)            : 30 
dumps(data, indent=2)  : 46 
dumps(data, separators): 25

通过移除多余的空白符,达到了压缩数据的目的,而且效果还是比较明显的。

另一个比较有用的dumps参数是skipkeys,默认为False。 dumps方法存储dict对象时,key必须是str类型,如果出现了其他类型的话,那么会产生TypeError异常,如果开启该参数,设为True的话,则会比较优雅的过度。

1
2
data =  { 'b' : 789 , 'c' : 456 ,( 1 , 2 ): 123 }
print  json.dumps(data,skipkeys = True )

输出:

{"c": 456, "b": 789}

 

处理自己的数据类型

json模块不仅可以处理普通的python内置类型,也可以处理我们自定义的数据类型,而往往处理自定义的对象是很常用的。

首先,我们定义一个类Person。

1
2
3
4
5
6
7
8
9
class  Person( object ):
     def  __init__( self ,name,age):
         self .name =  name
         self .age =  age
     def  __repr__( self ):
         return  'Person Object name : %s , age : %d'  %  ( self .name, self .age)
if  __name__  = =  '__main__' :
     p =  Person( 'Peter' , 22 )
     print  p

如果直接通过json.dumps方法对Person的实例进行处理的话,会报错,因为json无法支持这样的自动转化。通过上面所提到的json和python的类型转化对照表,可以发现,object类型是和dict相关联的,所以我们需要把我们自定义的类型转化为dict,然后再进行处理。这里,有两种方法可以使用。

方法一:自己写转化函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
'''
Created on 2011-12-14
@author: Peter
'''
import  Person
import  json
 
p =  Person.Person( 'Peter' , 22 )
 
def  object2dict(obj):
     #convert object to a dict
     d =  {}
     d[ '__class__' ] =  obj.__class__.__name__
     d[ '__module__' ] =  obj.__module__
     d.update(obj.__dict__)
     return  d
 
def  dict2object(d):
     #convert dict to object
     if '__class__'  in  d:
         class_name =  d.pop( '__class__' )
         module_name =  d.pop( '__module__' )
         module =  __import__ (module_name)
         class_  =  getattr (module,class_name)
         args =  dict ((key.encode( 'ascii' ), value) for  key, value in  d.items()) #get args
         inst =  class_ ( * * args) #create new instance
     else :
         inst =  d
     return  inst
 
d =  object2dict(p)
print  d
#{'age': 22, '__module__': 'Person', '__class__': 'Person', 'name': 'Peter'}
 
o =  dict2object(d)
print  type (o),o
#<class 'Person.Person'> Person Object name : Peter , age : 22
 
dump =  json.dumps(p,default = object2dict)
print  dump
#{"age": 22, "__module__": "Person", "__class__": "Person", "name": "Peter"}
 
load =  json.loads(dump,object_hook =  dict2object)
print  load
#Person Object name : Peter , age : 22

上面代码已经写的很清楚了,实质就是自定义object类型和dict类型进行转化。object2dict函数将对象模块名、类名以及__dict__存储在dict对象里,并返回。dict2object函数则是反解出模块名、类名、参数,创建新的对象并返回。在json.dumps 方法中增加default参数,该参数表示在转化过程中调用指定的函数,同样在decode过程中json.loads方法增加object_hook,指定转化函数。

方法二:继承JSONEncoder和JSONDecoder类,覆写相关方法

JSONEncoder类负责编码,主要是通过其default函数进行转化,我们可以override该方法。同理对于JSONDecoder。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
'''
Created on 2011-12-14
@author: Peter
'''
import  Person
import  json
 
p =  Person.Person( 'Peter' , 22 )
 
class  MyEncoder(json.JSONEncoder):
     def  default( self ,obj):
         #convert object to a dict
         d =  {}
         d[ '__class__' ] =  obj.__class__.__name__
         d[ '__module__' ] =  obj.__module__
         d.update(obj.__dict__)
         return  d
 
class  MyDecoder(json.JSONDecoder):
     def  __init__( self ):
         json.JSONDecoder.__init__( self ,object_hook = self .dict2object)
     def  dict2object( self ,d):
         #convert dict to object
         if '__class__'  in  d:
             class_name =  d.pop( '__class__' )
             module_name =  d.pop( '__module__' )
             module =  __import__ (module_name)
             class_  =  getattr (module,class_name)
             args =  dict ((key.encode( 'ascii' ), value) for  key, value in  d.items()) #get args
             inst =  class_ ( * * args) #create new instance
         else :
             inst =  d
         return  inst
 
 
d =  MyEncoder().encode(p)
o =   MyDecoder().decode(d)
 
print  d
print  type (o), o

 

对于JSONDecoder类方法,稍微有点不同,但是改写起来也不是很麻烦。看代码应该就比较清楚了。

转自:http://www.cnblogs.com/coser/archive/2011/12/14/2287739.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值