Django Rest Framework: adding DateTimeField format serializer validation
Flávia Bastos
Posted on February 15, 2023
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, 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.
If you found this helpful, please share this article.
The post Django Rest Framework: adding DateTimeField format serializer validation was originally published at flaviabastos.ca
Posted on February 15, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.