基于Auth0 Flask项目开发首个Python REST API时遇JSON序列化错误求助
嘿,刚上手Flask写REST API遇到这个坑太正常了!我来帮你捋清楚问题出在哪,以及怎么快速解决~
问题分析:为什么会出现
TypeError: ... is not JSON serializable? Flask自带的jsonify或者Python标准库的json.dumps只能序列化原生JSON支持的类型(比如字典、列表、字符串、数字、布尔值、None)。如果你的/products路由返回的是自定义类的实例(比如教程里可能定义了Product类,然后你存了一堆Product对象在列表里),这些对象不属于原生可序列化类型,就会触发这个错误。
举个例子,如果你写了类似这样的代码就会踩坑:
class Product: def __init__(self, id, name, price): self.id = id self.name = name self.price = price # 模拟产品数据 products = [ Product(1, "Wireless Headphones", 99.99), Product(2, "Portable Charger", 29.99) ] @app.route('/products', methods=['GET']) def get_products(): return jsonify(products) # 这里会直接报错!
解决方案:三种方法搞定序列化
根据你的项目规模,选适合的方法就行:
方法1:手动转成字典(快速简单,适合小项目)
在返回之前,把每个Product实例转换成字典——这是最直接的方式:
@app.route('/products', methods=['GET']) def get_products(): # 用列表推导式把每个实例转成字典 products_data = [ {"id": p.id, "name": p.name, "price": p.price} for p in products ] return jsonify(products_data)
方法2:给类添加序列化方法(复用性强)
给Product类加一个to_dict()方法,以后需要序列化的时候直接调用就行:
class Product: def __init__(self, id, name, price): self.id = id self.name = name self.price = price def to_dict(self): # 把实例属性打包成字典 return { "id": self.id, "name": self.name, "price": self.price } # 路由里这样用 @app.route('/products', methods=['GET']) def get_products(): products_data = [p.to_dict() for p in products] return jsonify(products_data)
方法3:自定义JSON编码器(适合大型项目)
如果你的项目里有很多自定义类需要序列化,自定义一个Flask的JSON编码器会更高效:
from flask import Flask, jsonify from flask.json import JSONEncoder class Product: def __init__(self, id, name, price): self.id = id self.name = name self.price = price def to_dict(self): return {"id": self.id, "name": self.name, "price": self.price} # 自定义编码器 class CustomJSONEncoder(JSONEncoder): def default(self, obj): # 如果是Product实例,调用to_dict() if isinstance(obj, Product): return obj.to_dict() # 其他类型交给默认编码器处理 return super().default(obj) # 把编码器绑定到Flask app app = Flask(__name__) app.json_encoder = CustomJSONEncoder # 现在直接返回实例列表就行 @app.route('/products', methods=['GET']) def get_products(): return jsonify(products)
额外提醒
如果你的数据里还有其他特殊类型(比如datetime日期对象),也要针对性处理——比如把日期转成ISO格式的字符串:datetime_obj.isoformat()。
内容的提问来源于stack exchange,提问作者Tommie Jones
相关产品推荐
相关产品推荐

