Trying to make a Django / Mezzanine "Page last updated by on date"

159 views Asked by At

I'm trying to make a "page last updated by (username)" on (date)" line at the bottom of my mezzanine site page. I've successfully got the date part with the syntax:

{{ page.updated|date:"M d, Y" }}

but the username seems more complicated. I have a nice list in django_admin_log containing action_time, user_id and object_id and I can access & display object_id from within my template using {{ page.id }}.

The username is in auth_user and in days of old I would have put in some SQL with a nice table join on user_id to retrieve this information and display it.

I can't seem to get the syntax right - this kind of thing looked promising:

page.objects.raw("select id, title from page")

but no matter how I try to massage it into my base.html with {{ xxx }} or {% xxx %}, I always seem to get an error.

Thanks for any pointers

2

There are 2 answers

0
Lysergia25 On

You should use the LogEntry model[1].

I would probably make a custom context processor[2] that get's the request's Page, finds the newest LogEntry for the Page instance and adds updated_on and updated_by context variables.

[1] https://github.com/django/django/blob/master/django/contrib/admin/models.py#L27

[2] https://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors

0
Julian Jordan On

I've found a way to do this:

I created a custom tag, saved in /appname/templatetags/appname_tags.py, code as follows:

from django import template
from django.db import connection

register = template.Library()

@register.inclusion_tag(‘appname/_updated_by.html')
def updated_by(pageid):
    cursor = connection.cursor()

    cursor.execute('select user_id from django_admin_log where object_id = %s order by id desc limit 1', [pageid])
    userid_set = cursor.fetchone()

    userid = userid_set[0]

    cursor.execute('select first_name, last_name from auth_user where id = %s', [userid])
    username = cursor.fetchone()

    return {'first_name': username[0],'last_name': username[1]}

This tag gets rendered via /appname/templates/appname/_updated_by.html, which simply contains:

{{ first_name }} {{ last_name }}

The whole thing then gets called from base.html via this code:

{% load appname_tags %}

And then add at the appropriate point:

Page Last Updated: {{ page.updated|date:"d/n/Y" }} by {% updated_by page.id %}

Hope this helps somebody, I'd be interested to hear if there's an easier / more elegant way to do this!