Keep a datetime.date in 'yyyy-mm-dd' format when using Flask's jsonify

前端 未结 3 1239
故里飘歌
故里飘歌 2020-12-05 18:36

For some reason, the jsonify function is converting my datetime.date to what appears to be an HTTP date. How can I keep the date in yyyy-mm-d

相关标签:
3条回答
  • 2020-12-05 19:12

    datetime.date is not a JSON type, so it's not serializable by default. Instead, Flask adds a hook to dump the date to a string in RFC 1123 format, which is consistent with dates in other parts of HTTP requests and responses.

    Use a custom JSON encoder if you want to change the format. Subclass JSONEncoder and set Flask.json_encoder to it.

    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__)
    

    It is a good idea to use ISO 8601 to transmit and store the value. It can be parsed unambiguously by JavaScript Date.parse (and other parsers). Choose the output format when you output, not when you store.

    A string representing an RFC 2822 or ISO 8601 date (other formats may be used, but results may be unexpected).

    When you load the data, there's no way to know the value was meant to be a date instead of a string (since date is not a JSON type), so you don't get a datetime.date back, you get a string. (And if you did get a date, how would it know to return date instead of datetime?)

    0 讨论(0)
  • 2020-12-05 19:19

    Following this snippet you can do this:

    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
    

    Route:

    import datetime as dt
    
    @app.route('/', methods=['GET'])
    def index():
        now = dt.datetime.now()
        return jsonify({'now': now})
    
    0 讨论(0)
  • 2020-12-05 19:24

    You can change your app's .json_encoder attribute, implementing a variant of JSONEncoder that formats dates as you see fit.

    0 讨论(0)
提交回复
热议问题