• 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)
    这时候就不会报错了。

    总结

    这两者都是django中后台返回给前台数据的方法,而且走的都是http协议

    区别

    HttpResponse需要前后台进行序列化和反序列化,JasonResponse把序列化和反序列化封装起来,传入可序列化字符串在前台就能收到对应数据.
    后端
    return HttpResponse(json.dumps(对象))
    return JasonResponse(对象)

    前端
    js反序列化 res=JSON.parse(data);
    序列化 JSON.stringify(res)
    JasonResponse 直接返回的值就是对应的数据类型,不需要过多操作,字典还可以进行对象点方法

    解决编码问题:

    return JsonResponse(data,json_dumps_params={'ensure_ascii':False})
    JasonResponse默认支持序列化字典,如果想要序列化其他类型(json能够支持的类型),只需要将safe参数有默认的True改为False

  • 相关阅读:
    关于RadAsm中GetEnvironmentStrings的BUG。
    GetStartupInfo 反调试
    基于TLS的反调试技术
    几种RAID级别的比较
    常用的外网yum源之epel.repo
    常用yum源之(Percona MySQL)
    swap的几点理解
    solaris系统动态查看swap的使用情况
    一次CTS引发的网络故障
    一次goldengate故障引发的操作系统hang起,HA自动切换
  • 原文地址:https://www.cnblogs.com/jhpy/p/11826153.html
Copyright © 2020-2023  润新知