使用 Flask 的 jsonify 时,以"yyyy-mm-dd"格式保留 datetime.date



出于某种原因,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的变体,该变体的格式化日期为适合。

相关内容

  • 没有找到相关文章

最新更新