Pour une raison quelconque, la fonction jsonify
convertit mon datetime.date
En ce qui semble être une date HTTP. Comment puis-je conserver la date au format yyyy-mm-dd
Lorsque j'utilise jsonify
?
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
Comme suggéré dans les commentaires, l'utilisation de jsonify(str(test_date))
renvoie le format souhaité. Cependant, considérez le cas suivant:
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"}"
Dans ce cas, la solution str()
ne fonctionne pas.
Après cet extrait vous pouvez le faire:
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})
datetime.date
n'est pas un type JSON, il n'est donc pas sérialisable par défaut. Au lieu de cela, Flask ajoute un crochet pour vider la date dans une chaîne au format RFC 112 , ce qui est cohérent avec les dates dans d'autres parties des requêtes et réponses HTTP.
Utilisez un encodeur JSON personnalisé si vous souhaitez modifier le format. Sous-classe JSONEncoder
et définissez 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__)
C'est une bonne idée d'utiliser ISO 8601 pour transmettre et stocker la valeur. Il peut être analysé sans ambiguïté par JavaScript Date.parse
(et autres analyseurs). Choisissez le format de sortie lorsque vous sortez, pas lorsque vous stockez.
Une chaîne représentant une date RFC 2822 ou ISO 8601 (d'autres formats peuvent être utilisés, mais les résultats peuvent être inattendus).
Lorsque vous chargez les données, il n'y a aucun moyen de savoir que la valeur était censée être une date au lieu d'une chaîne (puisque la date n'est pas un type JSON), donc vous n'obtenez pas de datetime.date
retour, vous obtenez une chaîne. (Et si vous aviez une date, comment saurait-elle retourner date
au lieu de datetime
?)
Vous pouvez modifier l'attribut .json_encoder
De votre application , en implémentant une variante de JSONEncoder
qui formate les dates comme bon vous semble.