[Django]-Datetime.date(2014, 4, 25) is not JSON serializable in Django

64👍

You can also do this:

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

print json.dumps(data, default=date_handler)

From here.

Update as per J.F.Sebastian comment

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

print json.dumps(data, default=date_handler)

14👍

Convert date to equivalent iso format,

In [29]: datetime.datetime.now().isoformat()
Out[29]: '2020-03-06T12:18:54.114600'

10👍

See the Extending encoder section from the json package docs https://docs.python.org/2/library/json.html

I have used this method and found it quite effective. I think this is what you are looking for.

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)

7👍

You can add a date time encoder into the JSON jumps function when handling model querysets, this is customised a bit as I had issues with the base django model state being parsed

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)

Then use this class with your json dumps

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

2👍

I’ve found this to be invaluable, especially after updating Django from 1.7 to 1.9. Most of this is from the blog http://arthurpemberton.com/2015/04/fixing-uuid-is-not-json-serializable
Put this in models.py right under the imports. It’ll take care of UUIDs for you too.

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

Leave a comment