Django Rest Framework: adding DateTimeField format serializer validation
Tags: python, todayilearned, webdev, django
Published: 2023-02-15 11:17:58

---
title: Django Rest Framework: adding DateTimeField format serializer validation
published: true
date: 2023-02-15 09:00:00 UTC
tags: python,til,webdevelopment,django
canonical_url: https://flaviabastos.ca/2023/02/15/django-rest-framework-adding-datetimefield-format-serializer-validation/
---

Here’s an example of adding date and time validation to a DateTimeField in a serializer in the Django Rest Framework (DRF).

A first pass, using only the default formats of DateTimeField(), would look like the following:

```
class CustomSearchFieldsSerializer(serializers.Serializer):
   start_time = serializers.DateTimeField()
   end_time = serializers.DateTimeField()
 
   def validate(self, data):
       # extra validation to ensure that the end date is always after the start date if data['start_time'] > data['end_time']:
           raise serializers.ValidationError("finish must occur after start")
       return data
```

Sending a request to that endpoint with the following query parameters (note it only has a date, not time):

```
/api/v1/custom-search/?start_time=2022-11-01&end_time=2022-11-07
```

Returns the following 400 Bad Request:

```
{
   "start_time": [
       "Datetime has wrong format. Use one of these formats instead: YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]."
   ],
   "end_time": [
       "Datetime has wrong format. Use one of these formats instead: YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]."
   ]
}
```

Not exactly what we want… I want this to be flexible and accept date only as a valid option.

Doing some research on the [Django Rest Framework (DRF) documentation](https://www.django-rest-framework.org/api-guide/fields/#datetimefield), I learned that I could customize the accepted formats. The next iteration looks like this:

```
class CustomSearchFieldsSerializer(serializers.Serializer):
   start_time = serializers.DateTimeField(required=False,
                                          input_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"])
   end_time = serializers.DateTimeField(required=False,
                                        input_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"])
```

The valid input formats can be passed as strings in a list. We add a few options, including a date-only format (the last option in the list).

Note: setting the flag “required” to False: this will make this field optional (in this case, the request could have no start and/or end time, which will then require the setting of some default values in the business logic to limit the query).

For the purposes of the task I was working on, I settled on the following formats:

```
input_formats=["%Y-%m-%d", "iso-8601"]

```

The first one accepts date only and the second follows the iso-8601 format, which is also the default format when nothing is set – the exact behaviour that we saw in the very first iteration. [iso-8601 is an international standard for the representation of date and time formats](https://www.w3.org/TR/NOTE-datetime).

* * *

If you found this helpful, please share this article.

The post [Django Rest Framework: adding DateTimeField format serializer validation](https://flaviabastos.ca/?p=770) was originally published at [flaviabastos.ca](https://flaviabastos.ca)