Turn an object list into a table django templatetags Part II

So this is a little more flexible than my last post. It's pretty much the same but it uses an html template so you have more control over the appearance and you can use the built-in filters such as "date."

from django import template
from django.core.urlresolvers import reverse
import datetime

@register.tag('make_table')
def do_make_table(parser, token):
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, object_list, caption, field_list = token.split_contents()
        field_list = field_list.replace('\"','')
        field_list = field_list.split(",")
        caption = caption.replace('\"','')
    except ValueError:
        raise template.TemplateSyntaxError("%r tag requires exactly three arguments" % token.contents.split()[0])
    return MakeTable(object_list,caption, field_list)

class MakeTable(template.Node):
    def __init__(self, object_list,caption, field_list):
        self.object_list = template.Variable(object_list )
        self.field_list = field_list
        self.caption = caption

    def render(self, context):
        try:
            object_list = self.object_list.resolve(context)
            if object_list.count() < 1:
               return ''
            if self.field_list[0] == "*" and object_list:
               self.field_list = object_list[0]._meta.get_all_field_names()

            th_fields=[]
            for field in self.field_list:
               th_fields.append(field.replace("_"," "))

            tr_rows =[]
            for obj in object_list:
              td_list=[]
              for field in self.field_list:
                this_field={}
                value = obj.__getattribute__(field.replace("'",""))
                if isinstance(value,datetime.datetime):
                   field_type="date"
                else:
                   field_type="text"
                if field == self.field_list[0]:
                   key = True
                   url = reverse('admin:%s_%s_change' %(obj._meta.app_label,obj.__class__.__name__.lower()), args=(obj.id,) )
                else:
                   url = None
                   key = False

                this_field = {'type':field_type,'value':value,'key':key,'url':url}
                td_list.append(this_field)
              tr_rows.append(td_list)

            t = template.loader.get_template('admin/ncm/make_table.html')
            c = template.Context({'caption':self.caption,'th_fields':th_fields,'tr_rows':tr_rows})
            rendered = t.render(c)
            return rendered
        except template.VariableDoesNotExist:
            return ''

admin/templates/ncm/make_table.html:

<table>
<caption>{{caption|title}}</caption>
<thead>
<tr>
{% for th in th_fields %}
        <th>{{th|title}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for tr  in tr_rows %}
        <tr>
        {% for field in tr %}
           <td>
           {% if field.key %}
                <a href="{{field.url}}">
           {% endif %}
              {% if field.type == "date" %}
                {{field.value|date:"F d, Y f a"}}
              {% else %}
                {{field.value|truncatechars:30}}
              {% endif %}
           {% if field.key %}
              </a>
           {% endif %}
           </td>
        {% endfor %}
        </tr>
{% endfor %}
</tbody>
</table>

Some django template: where outputs is a list of objects "Recent Outputs" is the caption, and a list of model fields to put in the table

{% load spur_admin_tags %}
<div class="module">
{% make_table outputs "Recent Outputs" "updated_on,job,node,performed_command,successful" %}
</div>
 

 
Tagged as django , render table , tags templatetags
Written by Andrew Konkol on July 24th, 2012

0 Comments

Log in with Twitter, Google, Facebook, LinkedIn to leave a comment.