As you might of reading I struggled getting data from an API into my Django templates. Once I did I came across another issue, dates…bloody full formatted dates. Dates formats such as this: 2019-08-30T08:22:32.245-0700 this was how the API presented one of the fields I needed.

How the hell could I convert it? I couldn’t just use datetime So off to Stackoverflow I went.

As the brilliant @Ralf said if the data I retrieved from the API was a string and not a Python datetime.datetime object. I had 2 options:

  • Custom template filter that converts string to date and formats it into a string with the desired format
  • In your view convert strings to dates and format them into strings with the desired format

The idea was to start creating a custom template filter. I copied the following from the source code from the built-in date filter so I was able to convert back to the date format I wanted, i ended up using ``

I then went ahead and used the following to create a custom template tag

Step 1

First I had to create a templatetags directory inside my app, at the same level as models.py, views.py, etc. I then had to create a __init__.py file to ensure the directory is treated as a Python package.

Within the templatetags dir I created my custom_date.py which would hold my custom filter. So the app layout would look something like this:

app/
    __init__.py
    models.py
    templatetags/
        __init__.py
        custom_date.py
    views.py

Step 2

Now on to adding the filter into custom_date.py going back to my Stackoverflow question, I copied the example Ralf created. Which is the below

from django import template
from django.utils import formats
import datetime
register = template.Library()


@register.filter(expects_localtime=True, is_safe=False)
def custom_date(value, arg=None):
    if value in (None, ''):
        return ''

    if isinstance(value, str):
        api_date_format = '%Y-%m-%dT%H:%M:%S.%f%z'  # 2019-08-30T08:22:32.245-0700
        value = datetime.datetime.strptime(value, api_date_format)

    try:
        return formats.date_format(value, arg)
    except AttributeError:
        try:
            return format(value, arg)
        except AttributeError:
            return ''

I had some bugs with api_date_format because the API produced a whole load of extras I checked out the datetstrftime() and strptime() Behavior table and made some edits. Once I got rid of the errors I moved on to the template.

First I had to load the custom filter into my template, then I used the custom_date to change it to what I needed.


<td class="text-center">{{ ticket.fields.updated|custom_date"Y,D,M" }}</td>

And there we have it…I successfully formatted the date, from an API response string.