web-dev-qa-db-fra.com

datetime.date (2014, 4, 25) n'est pas sérialisable JSON dans Django

J'ai suivi Comment surmonter "datetime.datetime not JSON serializable" en python? mais cela n'aide pas

J'ai essayé ce code

>>> import datetime
>>> a =datetime.date(2014, 4, 25)
>>> from bson import json_util
>>> b = json.dumps(a,default = json_util.default)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/home/.../python2.7/site-packages/bson/json_util.py", line 256, in default
    raise TypeError("%r is not JSON serializable" % obj)
TypeError: datetime.date(2014, 4, 25) is not JSON serializable

Quelqu'un peut-il m'aider avec un datetime.date sérialiseur et désérialiseur.

26

Vous pouvez également le faire:

def date_handler(obj):
    return obj.isoformat() if hasattr(obj, 'isoformat') else obj

print json.dumps(data, default=date_handler)

De ici .

Mise à jour selon le commentaire de J.F.Sebastian

def date_handler(obj):
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        raise TypeError

print json.dumps(data, default=date_handler)
64
AlexandruC

Convertissez la date en chaîne, puis essayez,

a = str( datetime.now() )
12
Nishant Nawarkhede

Voir la section Extension du codeur dans les documents du package json https://docs.python.org/2/library/json.html

J'ai utilisé cette méthode et l'ai trouvée assez efficace. Je pense que c'est ce que vous recherchez.

import json
class DatetimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
        Elif isinstance(obj, date):
            return obj.strftime('%Y-%m-%d')
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)

json.dumps(dict,cls=DatetimeEncoder)
9
Stephen Hartzell

Vous pouvez ajouter un encodeur date-heure dans la fonction de sauts JSON lors de la gestion des ensembles de requêtes de modèle, cela est un peu personnalisé car j'ai eu des problèmes avec l'état de base du modèle Django en cours d'analyse)

import datetime
import decimal
from Django.db.models.base import ModelState

class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
       if hasattr(obj, 'isoformat'):
           return obj.isoformat()
       Elif isinstance(obj, decimal.Decimal):
           return float(obj)
       Elif isinstance(obj, ModelState):
           return None
       else:
           return json.JSONEncoder.default(self, obj)

Ensuite, utilisez cette classe avec vos vidages json

b = json.dumps(a, cls = DateTimeEncoder)
7
Greg

J'ai trouvé que cela était inestimable, surtout après la mise à jour de Django de 1.7 à 1.9. La plupart provient du blog http://arthurpemberton.com/2015/04/ fixing-uuid-is-not-json-serializable Mettez ceci dans models.py juste sous les importations. Il prendra également soin des UUID pour vous.

from uuid import UUID
import datetime
JSONEncoder_olddefault = JSONEncoder.default
def JSONEncoder_newdefault(self, o):
    if isinstance(o, UUID): return str(o)
    if isinstance(o, datetime.datetime): return str(o)
    return JSONEncoder_olddefault(self, o)
JSONEncoder.default = JSONEncoder_newdefault
2
std''OrgnlDave