前言

flask 有个jsonify() 函数,如果返回的是一个字典,那么调用 jsonify 创建一个响应对象。

关于响应

视图函数的返回值会自动转换为一个响应对象。
如果返回值是一个字符串,那么会被 转换为一个包含作为响应体的字符串、一个 200 OK 出错代码 和一个 text/html 类型的响应对象。
如果返回值是一个字典,那么会调用 jsonify() 来产生一个响应。以下是转换的规则:

  • 如果视图返回的是一个响应对象,那么就直接返回它。
  • 如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的 响应对象。
  • 如果返回的是一个字典,那么调用 jsonify 创建一个响应对象。
  • 如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少 包含一个项目,且项目应当由 (response, status) 、 (response, headers) 或者 (response, status, headers) 组成。 status 的值会重载状态代码, headers 是一个由额外头部值组成的列表 或字典。
  • 如果以上都不是,那么 Flask 会假定返回值是一个有效的 WSGI 应用并把它转换为 一个响应对象。

jsonify() 响应对象

如果返回的是一个字典,那么调用 jsonify 创建一个响应对象
先看一个示例

from flask import Flask, jsonify
app = Flask(__name__)@app.route('/json', methods=['GET'])
def json_demo():return {"username": 'yoyo',"email": "111@qq.com"}if __name__ == '__main__':app.run()

接口返回

GET http://127.0.0.1:5000/json HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 51
Server: Werkzeug/2.0.2 Python/3.8.5
Date: Thu, 13 Oct 2022 02:49:38 GMT{"email": "111@qq.com", "username": "yoyo"
}

接口返回的是一个dict, 那么这时候会自动调用 jsonify 创建一个响应对象转成json格式,并且在返回头部带上Content-Type: application/json

我们也可以返回jsonify()函数,里面传一个字典,或者键值对的参数

from flask import Flask, jsonify
app = Flask(__name__)@app.route('/json1', methods=['GET'])
def json_demo1():return jsonify({"username": 'yoyo',"email": "111@qq.com"})@app.route('/json2', methods=['GET'])
def json_demo2():return jsonify(username="yoyo",email="111@qq.com")if __name__ == '__main__':app.run()

以上两种方式返回的结果都是

Content-Type: application/json
Content-Length: 51
Server: Werkzeug/2.0.2 Python/3.8.5
Date: Thu, 13 Oct 2022 02:56:15 GMT{"email": "111@qq.com", "username": "yoyo"
}

返回json字符串

如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的 响应对象。
我们试试自己返回一个json字符串,看看和jsonfy()处理过的有什么不一样

from flask import Flask, jsonify, json
app = Flask(__name__)@app.route('/json3', methods=['GET'])
def json_demo3():return json.dumps({"username": 'yoyo',"email": "111@qq.com"})if __name__ == '__main__':app.run()

接口返回内容

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 43
Server: Werkzeug/2.0.2 Python/3.8.5
Date: Thu, 13 Oct 2022 03:05:05 GMT{"email": "111@qq.com", "username": "yoyo"}

此时返回的"Content-Type"类型是"text/html; charset=utf-8",它是以文本的方式返回的,并不是以json方式返回,所以需要我们自己手动再加一个返回头部类型

@app.route('/json3', methods=['GET'])
def json_demo3():return json.dumps({"username": 'yoyo',"email": "111@qq.com"}), {"Content-Type": "application/json"}

改成上面的代码,才会返回"Content-Type": "application/json"

也就是说jsonify() 函数帮我们在返回头部自动带上"Content-Type": "application/json", 简化了操作。

jsonify() 源码解读

先看源码内容

def jsonify(*args: t.Any, **kwargs: t.Any) -> "Response":"""Serialize data to JSON and wrap it in a :class:`~flask.Response`with the :mimetype:`application/json` mimetype.Uses :func:`dumps` to serialize the data, but ``args`` and``kwargs`` are treated as data rather than arguments to:func:`json.dumps`.1.  Single argument: Treated as a single value.2.  Multiple arguments: Treated as a list of values.``jsonify(1, 2, 3)`` is the same as ``jsonify([1, 2, 3])``.3.  Keyword arguments: Treated as a dict of values.``jsonify(data=data, errors=errors)`` is the same as``jsonify({"data": data, "errors": errors})``.4.  Passing both arguments and keyword arguments is not allowed asit's not clear what should happen... code-block:: pythonfrom flask import jsonify@app.route("/users/me")def get_current_user():return jsonify(username=g.user.username,email=g.user.email,id=g.user.id,)Will return a JSON response like this:.. code-block:: javascript{"username": "admin","email": "admin@localhost","id": 42}The default output omits indents and spaces after separators. Indebug mode or if :data:`JSONIFY_PRETTYPRINT_REGULAR` is ``True``,the output will be formatted to be easier to read... versionchanged:: 2.0.2:class:`decimal.Decimal` is supported by converting to a string... versionchanged:: 0.11Added support for serializing top-level arrays. This introducesa security risk in ancient browsers. See :ref:`security-json`... versionadded:: 0.2"""indent = Noneseparators = (",", ":")if current_app.config["JSONIFY_PRETTYPRINT_REGULAR"] or current_app.debug:indent = 2separators = (", ", ": ")if args and kwargs:raise TypeError("jsonify() behavior undefined when passed both args and kwargs")elif len(args) == 1:  # single args are passed directly to dumps()data = args[0]else:data = args or kwargsreturn current_app.response_class(f"{dumps(data, indent=indent, separators=separators)}\n",mimetype=current_app.config["JSONIFY_MIMETYPE"],)

大概翻译下,jsonify 的作用是把数据序列化成JSON,并且在声明返回头部application/json,它返回一个Response 对象
它使用json.dumps 序列化数据, 但是 argskwargs 会被作为数据,而不是参数
1.如果是单个参数

jsonify('xx')

那么返回

Content-Type: application/json"xx"

2.如果是多个参数

jsonify(1, 2, 3)

那么等价于

jsonify([1, 2, 3])

都会返回

Content-Type: application/json[1, 2, 3
]

3.关键字参数

jsonify(data=data, errors=errors)

等价于

jsonify({"data": data, "errors": errors})

4.不允许同时传递args`参数和 kwargs``关键字参数,因为不清楚会发生什么.

默认情况下JSON输出会省略在分隔符后缩进和空格,起到了压缩数据的作用。(实际上就是用了 json.dumps(data, separators=(‘,’, ‘:’)) 处理。)
在debug模式或者我们设置了全局配置:JSONIFY_PRETTYPRINT_REGULARTrue,输出将被格式化以便于阅读。
示例,debug为False

@app.route('/json1', methods=['GET'])
def json_demo1():return jsonify(username='yoyo',email="111@qq.com")if __name__ == '__main__':app.run(debug=False)

启动日志看到debug模式关闭了

 * Serving Flask app 'app' (lazy loading)* Environment: development* Debug mode: off

次数输出的json格式会被去掉空格和缩进,可以起到压缩数据作用

Content-Type: application/json{"email":"111@qq.com","username":"yoyo"}

为了方便阅读,我们可以开启debug模式,或者添加全局配置JSONIFY_PRETTYPRINT_REGULARTrue

if __name__ == '__main__':app.run(debug=True)

启动日志

 * Serving Flask app 'app' (lazy loading)* Environment: development* Debug mode: on

此时返回的json格式就是被美化过

{"email":"111@qq.com","username":"yoyo"}

其原理实际上就是用了 json.dumps()的 indent和 separators=(‘,’, ‘:’)处理

使用总结

总的来说有以下几点功能
1.如果返回值是一个字典,那么会调用 jsonify() 来产生一个响应
2.jsonify 返回的Response的headers属性为:Content-Type: application/json ,是标准的json格式。
3.jsonify自动去除了JSON格式中逗号冒号间的空格,起到了压缩数据的作用。

Flask 学习-88. jsonify() 函数源码解读深入学习相关推荐

  1. python内置函数源码_如何查看python内置函数源码

    在用Python进行各种分析的时候,我们会用到各种各样的函数,比如,我们用SQL时,经常使用join.max等各种函数,那么想看Python是否有这个函数,这个时候可能大部分人会百度,那么如何不使用百 ...

  2. OpenCV resize函数源码解析——加速方法

    相信大家应该经常会用到OpenCV中的函数resize(),当我们想放大或者缩小图像的时候,会用到这个函数进行图像缩放,其中最核心的便是对图像的像素进行插值处理. 这里的插值interpolation ...

  3. LMDIF_函数源码

    函数源码: /* lmdif.f -- translated by f2c (version 20020621).You must link the resulting object file wit ...

  4. 【Linux 内核】实时调度类 ⑦ ( 实时调度类核心函数源码分析 | dequeue_task_rt 函数 | 从执行队列中移除进程 )

    文章目录 一.dequeue_task_rt 函数 ( 从执行队列中移除进程 ) 二.update_curr_rt 函数 ( 更新调度信息 ) 本篇博客中 , 开始分析 struct sched_cl ...

  5. 【Linux 内核】实时调度类 ⑥ ( 实时调度类核心函数源码分析 | 插入进程到执行队列 | 从执行队列中选择优先级最高的进程 )

    文章目录 一.enqueue_task_rt 函数 ( 插入进程到执行队列 ) 二.pick_next_task_rt 函数 ( 从执行队列中选择优先级最高的进程 ) 本篇博客中 , 开始分析 str ...

  6. 【Android 逆向】ART 脱壳 ( dex2oat 脱壳 | aosp 中搜索 dex2oat 源码 | dex2oat.cc#main 主函数源码 )

    文章目录 前言 一.搜索 dex2oat 源码 二.dex2oat.cc#main 主函数源码 前言 在 [Android 逆向]ART 脱壳 ( DexClassLoader 脱壳 | exec_u ...

  7. PHP 源码 —— is_array 函数源码分析

    is_array 函数源码分析 本文首发于 https://github.com/suhanyujie/learn-computer/blob/master/src/function/array/is ...

  8. [OpenGL] 视图矩阵(View)矩阵与glm::lookAt函数源码解析

    一.视图矩阵(View)矩阵 首先明确视图矩阵的作用:在OpenGL的众多坐标系中,存在一个世界坐标系和一个摄像机坐标系,视图矩阵的作用就是将世界坐标系内的坐标转换成摄像机坐标系内的坐标. 如图,空间 ...

  9. 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )

    文章目录 一.retry 标号代码分析 二.retry 标号完整代码 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分析 | __allo ...

最新文章

  1. [LeetCode]题解(python):108-Convert Sorted Array to Binary Search Tree
  2. Spring Boot与ActiveMQ的集成
  3. gzip压缩算法: gzip 所使用压缩算法的基本原理
  4. Zookeeper的Windows安装
  5. 深入浅出根据函数调用过程谈栈回溯原理
  6. 深度学习特征归一化方法——BN、LN、IN、GN
  7. 由Google Protocol Buffer的小例子引起的g++编译问题
  8. 用正则判断字符串是否为中文的方法
  9. mysql 并发 锁表_MySQL中的锁(表锁、行锁) 并发控制锁
  10. 高斯混合模型聚类_GMM: Gaussian Mixed Model(高斯混合模型)
  11. Pygal简单使用——模拟掷骰子
  12. MySQL为啥不用平衡二叉树_MySQL的索引,为什么是B+而不是平衡二叉树
  13. 怎么把电脑计算机桌面调出来,手把手教你电脑怎么设置屏保
  14. 使用ssh远程连接家庭电脑
  15. java.util.concurrent 同步器框架详解
  16. 应广PFS122单片机比较器测供电电源VDD电压带临界点消抖处理
  17. sap销售发货的流程_SAP标准业务流程-销售订单处理
  18. Android ScrollView scrollbarStyle 样式详解
  19. 初识c语言(入门篇)
  20. Photoshop给图片替换蓝天白云背景

热门文章

  1. Qt-configure参数说明
  2. 如何画一个简单的波特图(渐近线近似零极点特性)?
  3. 面试题之this的指向
  4. 若int a = 0, b = 1, c = 2,则逻辑表达式a++ b++ || (c -= 2)执行之后
  5. ISMS与信息安全的三观论
  6. OnlyOffice验证(二)在Centos7上部署OnlyOffice编译结果
  7. 【论文笔记】迁移自适应学习综述
  8. MySQL中+(加号)
  9. 如何抓住风口,利用互联网赚钱?(內含三大商业模式推荐)建议收藏
  10. C#计算伪逆矩阵(PseudoInverse)