Displaying the last modification date of the template file

Hi,

I’m wondering is there a way to display the last modification date of the template file on the template itself? I’m currently building static HTML www-pages with Django and would like to show to the visitor when the contents of the page (the template content) has been last modified. Something like ‘Page updated on November 29, 2019’.

Basically my views.py point to several template files, like:
def index(request):
return render(
request,
‘index.html’,
)

Any help will be appreciated,
-Kari

Is this the sole reason that you are bringing in the Django backend for a static site? I ask because Django seems like some serious overkill for this. I’m also interested in how others may try to accomplish this but I’ll give it a try. I use Ubuntu as my operating system so the answer will be tested for my OS. The steps should be similar but you may need to translate my solution to your OS.

The general idea of what I would do is have a model in Django that keeps track of template updates. It can be really simple.

class TemplateUpdate(models.Model):
    name = models.CharField(max_length=50)
    update_dt = models.CharField(max_length=50)

Next you need to decide an interval to poll your templates directory. I would run a cronjob on this interval.

You need a way to create a model object. You could create an API endpoint that updates the time of a given template object. Or do something like assuming you have the template name

manage.py shell --command="from path.to.app.models import TemplateUpdate;from django.utils import timezone;t=TemplateUpdate.objects.get(name=passed_name);t.update_dt=timezone.now();t.save();"

Basically you need to find a way to do the following:
1.) Get the modified date of a file. Ubuntu 16.04 ex.

stat path/to/file | grep "Modify"

2.) Update template object to reflect updated date via API or shell command as mentioned

3.) Combine the previous two scripts into a shell script for your OS

4.) Run the script on a set interval.

Pseducode

!/bin/bash

modified_dt = stat path/to/template.html | grep "Modify"
#api post request to update.. this part is on you

Now run this on a cronjob- this example is minutely

* * * * * /bin/sh /path/to/script.sh >> /dev/null

Now your Template object is being updated minutely. Pass the update_dt to the front end as a context variable and render it.

Considering my solution is already doing a lot with the system it may be easier to avoid bringing in Django dependencies and update the static file manually with the update date.

Hi Nate,
thank you for the answer. Yes, currently it is overkill as I’m displaying quite static (very old) Html files. My aim is to gradually update the contents (different lists) directly from the database using Models.

I also Googled this last modification date problem and ended up in this solution:

views.py
import os.path, time
from settings import BASE_DIR

This needs to be defined for all html file calls
def index(request):
file=os.path.join(BASE_DIR,‘app’, ‘templates’, ‘index.html’)
last_modified=time.ctime(os.path.getmtime(file))
return render(
request,
‘index.html’,
context={‘last_modified’:last_modified,},
)

index.html
{% extends “base_generic.html” %}

base_generic.html

Page updated on:

{{ last_modified }}

Works just fine, but still is not quite DRY. Any improvements for this code?

Nice solution, I see what you mean about it not being DRY though. I’m thinking you use a decorator to apply this functionality.

from django.conf import settings
from django.urls import resolve
import os, time
from django.template.response import TemplateResponse  

def add_mod_date(template):
    def outer_wrapper(func):
        def wrapper(request, *args, **kwargs):
           template_path = os.path.join(settings.BASE_DIR, resolve(request.path).app_name, settings.TEMPLATE_URL, template)
           r = func(request, *args, **kwargs)
           r.context_data = {"last_modified": time.ctime(os.path.getmtime(template_path))}
           return r.render()
        return wrapper
    return outer_wrapper

# Create your views here.
@add_mod_date("index.html")
def sample(request):
    return TemplateResponse(request, "index.html")

You will need to define app_name=“my_app_name” within urls.py. Additionaly, declare TEMPLATE_URL = “templates” within settings.py.

Now within the template you can access {{ last_modified }} on all templates with the decorator
@add_mod_date("file_name.html")
I.e you can do the following in the template without adding the context variable explicitly in the view.

{{ last_modified }}

Hi Nate,
thank you for your nice solution.
I have now implemented it here: https://nowdatabase.org/

1 Like