Search code examples
pythondjangodatetimetimezonetastypie

Tastypie 0.9.6: datetime serialization is not tz-aware


We're using tastypie to manage our RESTful web API, all of it over django. Django is set with USE_TZ=True, tastypie with TASTYPIE_DATETIME_FORMATTING='iso-8601'.

I would expect the datetime fields to look like '2014-02-11T13:08:03+00:00'.

However, the serialized json bundles sent to the client never contain the dates as TZ aware dates, but rather server-local-tz converted, and with the TZ info stripped.

The date above is serialized as '2014-02-11T14:08:03' (I'm in the timezone Europe/Paris). For now, we have to guess the server's timezone when parsing on client side, and we don't like this hack :)

The tastypie resource description is pretty straightforward.

Are we doing something wrong or forgetting something?

Thanks, cheers.


Solution

  • The simple workaround for this is adding own serializer:

    class ISO8601UTCOffsetSerializer(Serializer):
        """
        Default is ``iso-8601``, which looks like "2014-01-21T19:31:58.150273+00:00".
        """
        # Tastypie>=0.9.6,<=0.11.0
        def format_datetime(self, data):
            # data = make_naive(data) # Skipping this line..
    
            if self.datetime_formatting == 'rfc-2822':
                return dateformat.format(make_naive(data), 'r')
            if self.datetime_formatting == 'iso-8601-strict':
                # Remove microseconds to strictly adhere to iso-8601
                data = data - datetime.timedelta(microseconds=data.microsecond)
    
            return data.isoformat()
    
    class MyResource(BaseModelResource):
        class Meta:
            serializer = ISO8601UTCOffsetSerializer(formats=['json'])
    

    Tastypie has thrown away timezone info and convert aware datetime to server datetime without timezone info. The above code shows how to fix it. Tastypie does it because some incompatibility with MySQL databases and back-compability with older Django versions I guess, discussion about is on github.