Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding timedelta support to JSONEncoder, and an example of how to add decode support to a serializer. #584

Merged
merged 1 commit into from
Jan 15, 2013

Conversation

radiosilence
Copy link
Contributor

Whilst this commit adds encoding of timedeltas to a string of a floating
point value of the seconds, you must add your own serializer field for
whatever timedelta model field you are using. This is because Django doesn't
support any kind of timedelta field out-of-the-box, so you have to either
implement your own or use django-timedelta.

If this is the case and you want to serialise timedelta input, you will have
to implement your own special field to use for the timedelta, which is not
included in core as it is based on a 3rd party library. Here is an example:

import datetime
import timedelta
from django import forms
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from rest_framework.fields import WritableField

class TimedeltaField(WritableField):
    type_name = 'TimedeltaField'
    form_field_class = forms.FloatField

    default_error_messages = {
        'invalid': _("'%s' value must be in seconds."),
    }

    def from_native(self, value):
        if value in validators.EMPTY_VALUES:
            return None

        try:
            return datetime.timedelta(seconds=float(value))
        except (TypeError, ValueError):
            msg = self.error_messages['invalid'] % value
            raise ValidationError(msg)

Which is based on the FloatField. This field can then be used in
your serializer like this:

from yourapp.fields import TimedeltaField

class YourSerializer(serializers.ModelSerializer):
    duration = TimedeltaField()

Whilst this commit adds *encoding* of timedeltas to a string of a floating
point value of the seconds, you must add your own serializer field for
whatever timedelta model field you are using. This is because Django doesn't
support any kind of timedelta field out-of-the-box, so you have to either
implement your own or use django-timedelta.

If this is the case and you want to serialise timedelta input, you will have
to implement your own special field to use for the timedelta, which is not
included in core as it is based on a 3rd party library. Here is an example:

    import datetime
    import timedelta
    from django import forms
    from django.core import validators
    from django.core.exceptions import ValidationError
    from django.utils.translation import ugettext_lazy as _
    from rest_framework.fields import WritableField

    class TimedeltaField(WritableField):
        type_name = 'TimedeltaField'
        form_field_class = forms.FloatField

        default_error_messages = {
            'invalid': _("'%s' value must be in seconds."),
        }

        def from_native(self, value):
            if value in validators.EMPTY_VALUES:
                return None

            try:
                return datetime.timedelta(seconds=float(value))
            except (TypeError, ValueError):
                msg = self.error_messages['invalid'] % value
                raise ValidationError(msg)

Which is based on the FloatField. This field can then be used in
your serializer like this:

    from yourapp.fields import TimedeltaField

    class YourSerializer(serializers.ModelSerializer):
        duration = TimedeltaField()
@tomchristie
Copy link
Member

Thx dude. Good point re. time delta fields.

tomchristie added a commit that referenced this pull request Jan 15, 2013
Adding timedelta support to JSONEncoder, and an example of how to add decode support to a serializer.
@tomchristie tomchristie merged commit 685706f into encode:master Jan 15, 2013
@tomchristie
Copy link
Member

Reference for anyone coming across this searching for time delta support in REST framework...
As of this fix, you should now be able to use custom TimeDelta fields, as provided by eg. http://pypi.python.org/pypi/django-timedeltafield

@radiosilence
Copy link
Contributor Author

It's weird, as timedelta seems like a primitive that Django should have a field for in core, really. Then we could have it in our core, too.

@tomchristie
Copy link
Member

Could try opening a ticket for it. They might go for it.

@tomchristie
Copy link
Member

@jpadilla
Copy link
Member

Django 1.8 has support for DurationField. This PR is partly related. Tracking support for Django 1.8's Duration field in #2481.

treyhunner pushed a commit to treyhunner/django-rest-framework that referenced this pull request Sep 16, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants