json實現不支持轉換數據類型得轉換
當我們用json模塊的dumps把一種json模塊不支持的數據類型進行轉換成json字符串的時候,會報錯
TypeError: Object of type 'datetime' is not JSON serializable
“datetime 類型的對象不能被json解析”
但是現在的業務邏輯是我們非要讓他能夠解析,這時候看他的源碼。
先進入到dumps的源碼之中
def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
看見里面有一個 cls = None,這時候先不要看cls是什么,然后往下看,找到了一個
if cls is None:
cls = JSONEncoder
點進去 JSONEncoder 看他的源碼,
def default(self, o):
"""Implement this method in a subclass such that it returns
a serializable object for ``o``, or calls the base implementation
(to raise a ``TypeError``).
For example, to support arbitrary iterators, you could
implement default like this::
def default(self, o):
try:
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
# Let the base class default method raise the TypeError
return JSONEncoder.default(self, o)
"""
raise TypeError("Object of type '%s' is not JSON serializable" %
o.__class__.__name__)
看到了這句拋出異常,和我們的報錯是一樣的,所以,我們這時候可以通過重寫這個 JSONEncoder類的default方法,來實現我們要的業務邏輯。
class MyJsonClass(json.JSONEncoder):
def default(self, o):
if isinstance(o,datetime): # 如果o不是json默認能夠序列化 你就在該方法內給他處理成json能夠轉的類型
return o.strftime('%Y-%m-%d')
else:
super().default(self,o)
比如我們要dumps的對象是一個datetime類型的數據,那么這里的isinstance第二個參數就寫這個,判斷來的對象是不是他的子類,是的話,就手動給他轉換了,再返回,當然不是這種類型的時候要繼續使用之前的功能,所以調用父類的default方法。
d = {'ctime':datetime.today()}
print(json.dumps(d,cls=MyJsonClass))
這時候在這里面寫一個cls=MyJsonClass,就可以了,再看下去源碼就是講json是怎么序列化的了。
JsonResponse
Django有一個簡單的方法,不需要我們去導入json模塊,然后序列化了,
先導入以下模塊
from django.http import JsonResponse
然后再調用就可以了
l = [1,2,3,4,5,5,6]
return JsonResponse(user,json_dumps_params={'ensure_ascii':False})
json_dumps_params是什么?進JsonResponse的源碼看一下。
class JsonResponse(HttpResponse):
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if safe and not isinstance(data, dict):
raise TypeError(
'In order to allow non-dict objects to be serialized set the '
'safe parameter to False.'
)
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super(JsonResponse, self).__init__(content=data, **kwargs)
Django模塊就是賤,叫我們不要導入json模塊,用他的JsonResponse,而他自己
JsonResponse實現的方法卻依然是基於json模塊的,好惡心啊,**json_dumps_params就是參數咯,所以我們只需要像上面那樣寫,帶一個字典,它會把它打散成關鍵字參數,這時候就可以寫入 ensure_ascii':False 了,他的作用是不讓中文字符直接被轉碼成字節了。
現在進行一個操作:
l = [1,2,3,4,5,5,6]
return JsonResponse(l)
結果卻報錯了
錯誤信息
TypeError at /index/
In order to allow non-dict objects to be serialized set the safe parameter to False.
"為了允許序列化非dict對象,請將安全參數設置為False。"
那我們就去設置就好了
l = [1,2,3,4,5,5,6]
return JsonResponse(l,safe=False)
這時候就不會報錯了。
JsonResponse默認只支持序列化字典 如果你想序列化其他類型(json能夠支持的類型) 你需要將safe參數由默認的True改成False