Django Rest Framework how to post date field

13,031

You can modify your date field in your serializer with a different format (different from the default one, which you are using implicitly).

More info:

https://www.django-rest-framework.org/api-guide/fields/#datefield

https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior

from rest_framework import serializers, fields


class EventSerializer(serializers.ModelSerializer):

    date = fields.DateField(input_formats=['%Y-%m-%dT%H:%M:%S.%fZ'])

    class Meta:
        model = Event
        fields = ('id', 'name', 'date')

Note that if you need to parse timestamps other than in UTC (Z at the end of your timestamp), you will need to customize DateField a bit more.

As @nitrovatter mentioned in the comments, the date input formats can also be configured in the settings to affect every serializer by default. For example:

REST_FRAMEWORK = {
    'DATE_INPUT_FORMATS': ['iso-8601', '%Y-%m-%dT%H:%M:%S.%fZ'],
}
Share:
13,031

Related videos on Youtube

nitrovatter
Author by

nitrovatter

Updated on September 15, 2022

Comments

  • nitrovatter
    nitrovatter over 1 year

    I want to post JSON request with field date:

    {
        "date":"2015-02-11T00:00:00.000Z"
    }
    

    It's the string is automatically converted from Date object and I don't want to crop the part T00:00:00.000Z manually at frontend.

    But if I post such request, Django Rest Framework validator of DateField will say me, that date has invalid format.

    My model:

    class Event(models.Model):
        name = models.CharField('Name', max_length=40, blank=True, null=True)
        date = models.DateField('Date', blank=True, null=True)
    

    My serializer:

    class EventSerializer(serializers.ModelSerializer):
        class Meta:
            model = Event
            fields = ('id', 'name', 'date')
    

    What is the right way to solve this problem?

  • nitrovatter
    nitrovatter over 5 years
    Is the code of the serializer correct? Should it be date = DateField(input_formats=['%Y-%m-%dT%H:%M:%S.%fZ'])?
  • JoseKilo
    JoseKilo over 5 years
    This works for example: datetime.strptime("2015-02-11T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"). But note that the Z is hardcoded, see my last paragraph. Do you need to parse any possible timezone ?
  • nitrovatter
    nitrovatter over 5 years
    In my specific case, I may not parse any possible timezones. But if it's easy to make the general solution for all timezones, I would know it.
  • JoseKilo
    JoseKilo over 5 years
    Also, I've fixed the typo, you were right: I missed the date = bit
  • JoseKilo
    JoseKilo over 5 years
    Tested on the shell: EventSerializer(data={'date': '2015-02-11T00:00:00.000Z'}).is_valid() returns True. But this EventSerializer(data={'date': '__WRONG__'}).is_valid() return False and the error that you mention is stored in serializer.errors.
  • nitrovatter
    nitrovatter over 5 years
    Yeah! It works! Sorry for false statement before and thank you very much! I've added the following string to config, to deliver me from necessity to add that string in each serializator: REST_FRAMEWORK = { 'DATE_INPUT_FORMATS': ['iso-8601', '%Y-%m-%dT%H:%M:%S.%fZ'] }
  • JoseKilo
    JoseKilo over 5 years
    Oh yes, that's also possible. I will add it to the answer in case someone else needs it.