出于某种原因,jsonify
函数将我的datetime.date
转换为似乎是HTTP日期。使用jsonify
时,如何将日期保留为yyyy-mm-dd
格式?
test_date = datetime.date(2017, 4, 27)
print(test_date) # 2017-04-27
test_date_jsonify = jsonify(test_date)
print(test_date_jsonify.get_data(as_text=True)) # Thu, 27 Apr 2017 00:00:00 GMT
如注释中建议的,使用jsonify(str(test_date))
返回所需的格式。但是,请考虑以下情况:
test_dict = {"name": "name1", "date":datetime.date(2017, 4, 27)}
print(test_dict) # {"name": "name1", "date":datetime.date(2017, 4, 27)}
test_dict_jsonify = jsonify(test_dict)
print(test_dict_jsonify.get_data(as_text=True)) # {"date": "Thu, 27 Apr 2017 00:00:00 GMT", "name": "name1"}
test_dict_jsonify = jsonify(str(test_dict))
print(test_dict_jsonify.get_data(as_text=True)) # "{"date": datetime.date(2017, 4, 27), "name": "name1"}"
在这种情况下,str()
解决方案不起作用。
编辑:现在,对于烧瓶版本,此答案太旧了2.3 。
对于这些较新版本,而是自定义json_provider_class
;参考:https://flask.palletsprojects.com/en/2.2.x/api/?highlight = json_encoder#flask.flask.flask.json_provider_class_class
遵循此片段,您可以执行此操作:
from flask.json import JSONEncoder
from datetime import date
class CustomJSONEncoder(JSONEncoder):
def default(self, obj):
try:
if isinstance(obj, date):
return obj.isoformat()
iterable = iter(obj)
except TypeError:
pass
else:
return list(iterable)
return JSONEncoder.default(self, obj)
app = Flask(__name__)
app.json_encoder = CustomJSONEncoder
路线:
import datetime as dt
@app.route('/', methods=['GET'])
def index():
now = dt.datetime.now()
return jsonify({'now': now})
datetime.date
不是JSON类型,因此默认情况下不可序列化。取而代之的是,烧瓶添加了一个挂钩,将日期转储到RFC 1123格式的字符串中,该格式与HTTP请求和响应其他部分中的日期一致。
如果要更改格式,请使用自定义JSON编码器。子类JSONEncoder
并将Flask.json_encoder
设置为它。
from flask import Flask
from flask.json import JSONEncoder
class MyJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, date):
return o.isoformat()
return super().default(o)
class MyFlask(Flask):
json_encoder = MyJSONEncoder
app = MyFlask(__name__)
使用ISO 8601传输和存储该值是一个好主意。可以通过JavaScript Date.parse
(和其他解析器(明确解析它。在输出时选择输出格式,而不是存储时。
代表RFC 2822或ISO 8601日期的字符串(可以使用其他格式,但结果可能是出乎意料的(。
加载数据时,没有办法知道该值是一个日期而不是字符串(因为日期不是JSON类型(,因此您没有回到datetime.date
,您会得到一个字符串。(如果您确实得到了约会,它将如何知道返回date
而不是datetime
?(
烧瓶2.2显示折旧警告
'JSONEncoder' is deprecated and will be removed in Flask 2.3. Use 'Flask.json' to provide an alternate JSON implementation instead.
需要进行更新以将其删除和/或在烧瓶2.3 中工作。来自烧瓶存储库的另一个示例
from datetime import datetime, date
from flask import Flask
from flask.json.provider import DefaultJSONProvider
class UpdatedJSONProvider(DefaultJSONProvider):
def default(self, o):
if isinstance(o, date) or isinstance(o, datetime):
return o.isoformat()
return super().default(o)
app = Flask(__name__)
app.json = UpdatedJSONProvider(app)
您可以更改应用程序的 .json_encoder
属性,实现 JSONEncoder
的变体,该变体的格式化日期为适合。