Converting dates from an API response in a Django Template
Tags: python, django, tutorial
Published: 2020-06-12 20:02:48

As you might of read I struggled [getting data from an API](https://developer.mrpbennett.com/2019/09/02/getting-api-data-into-your-templates-with-django/) 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 data format was how the API presented one of the fields I needed.

How the hell could I convert it? I couldn't just use [`datetime`](https://docs.python.org/2/library/datetime.html) So off to [Stackoverflow](https://stackoverflow.com/questions/57759653/how-to-convert-date-from-an-api-response-in-a-django-template) 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](https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/#writing-custom-template-filters). I copied the following from the source code from the [built-in date filter](https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#date) so I was able to convert back to the date format I wanted, i ended up using `{{ custom_date:"d/b/y" }}`

I then went ahead and used the following to create a [custom template tag](https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/#code-layout)

### 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:

```bash
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

```python
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](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) 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.

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

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