Json與JsonResponse


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


免責聲明!

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



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