JsonResponse是Django专用类,jsonify是Flask专用函数,二者不可混用;Django返回list需设safe=False,Flask的jsonify不支持自定义对象需先转dict,中英文编码、日期、None处理需显式控制。

用 JsonResponse 还是 jsonify?看框架
不是“哪个更好”,而是“你用的是 Django 还是 Flask”——JsonResponse 是 Django 的类,jsonify 是 Flask 的函数,两者不兼容、不能混用。选错直接报错:ModuleNotFoundError: No module named 'flask' 或 NameError: name 'jsonify' is not defined。
常见错误现象:把 Flask 教程里的 jsonify(data) 粘贴进 Django 视图,或者反过来在 Flask 里写 return JsonResponse(...),结果连服务都起不来。
- Django 项目必须用
JsonResponse(来自django.http) - Flask 项目必须用
jsonify(来自flask) - 纯 Python 脚本或非 Web 场景,就别碰这两个,直接用
json.dumps()+HttpResponse(Django)或手动设Content-Type(Flask)
JsonResponse 默认只序列化 dict,list 要加 safe=False
Django 的 JsonResponse 默认只接受字典类型,传 list 会抛出 TypeError: In order to allow non-dict objects to be serialized...。这不是 bug,是设计限制,防 XSS(比如返回 [1,2,3] 可能被恶意 script 注入)。
使用场景:API 返回分页列表、搜索结果数组、图表数据点集合——这些基本都是 list。
立即学习“Python免费学习笔记(深入)”;
- 想返回 list,必须显式写
JsonResponse(data, safe=False) - 如果 data 是 dict,
safe=True(默认)完全够用,不用改 -
safe=False不影响性能,但要确保你清楚返回的是什么结构,别把用户可控输入直接塞进去再safe=False
from django.http import JsonResponse
<p>def api_list(request):
items = [{"id": 1, "name": "a"}, {"id": 2, "name": "b"}]
return JsonResponse(items, safe=False) # 必须加 safe=False
jsonify 自动处理嵌套、datetime 和 None,但不递归编码自定义对象
Flask 的 jsonify 比 json.dumps 多一层封装:它自动把 datetime 转成 ISO 字符串,把 None 当作 null,还能扁平化多层 dict。但它不会碰你自定义的类实例。
常见错误现象:返回一个 User 对象,得到 TypeError: Object of type User is not JSON serializable。
-
jsonify只对内置类型(dict/list/str/int/float/bool/None/datetime)友好 - 遇到模型实例、SQLAlchemy 对象、dataclass,得先用
.to_dict()或model_to_dict()转成 dict - 别依赖
jsonify(obj)“自动搞定”,它不自动调用__dict__或asdict()
from flask import jsonify
from datetime import datetime
<p>@app.route('/now')
def now():
return jsonify({
"time": datetime.now(), # ✅ 自动转成字符串
"data": None, # ✅ 自动转成 null
"user": user_obj # ❌ 报错,得先 user_obj.to_dict()
})中文乱码、日期格式、空值处理——三个最容易漏掉的细节
哪怕选对了函数、参数也写对了,上线后还是可能出问题:前端收到一堆 ,时间字段变成毫秒数字,或者 null 被当成字符串 "null"。
- Django:
JsonResponse默认用 UTF-8,但如果你手动拼接了HttpResponse(json.dumps(...), content_type='application/json'),记得加ensure_ascii=False,否则中文变 Unicode 转义 - Flask:
jsonify默认ensure_ascii=False,但如果你重写了app.json_encoder,就得自己保证编码逻辑 - 日期统一用
datetime.isoformat()或序列化前转字符串,别依赖框架默认(Django 会转,Flask 会转,但格式可能不一致) -
None在 JSON 中是null,但如果你用json.dumps({'x': None})再包一层JsonResponse,没问题;可如果中间经过 str 拼接或 f-string,None就变成字符串"None",前端解析失败
该处理的边界情况其实就这几处:框架归属、list 安全开关、自定义对象预处理、字符与空值表达。漏掉任意一个,前端拿到的就是半截数据或解析错误。










