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

Turn an object list into a table with django templatetags

/project/myapp/myapp_admin_tags.py:

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


register = template.Library()

@register.tag(name="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:
caption_html="<caption>%s</caption>" %( self.caption)

object_list = self.object_list.resolve(context)
th_fields = self.field_list

th_html=""
for th in th_fields:
th_html += "<th>%s</th>" %(th.replace("_"," ").capitalize())
thead = "<thead><tr>%s</tr></thead>" %(th_html)

tr_html=""
for obj in object_list:
td_html=""
for field in self.field_list:
if field == th_fields[0]: #is first col in list
url = reverse('admin:%s_%s_change' %(obj._meta.app_label,obj.__class__.__name__.lower()), args=(obj.id,) )
td_html += "<td><a href='%s'>%s</a></td>" %(url,obj.__getattribute__(field.replace("'","")))
else:
td_html += "<td>%s</td>" %(obj.__getattribute__(field.replace("'","")))
tr_html += "<tr>%s</tr>" % (td_html)
table_html = "<table>%s %s %s</table>" %(caption_html, thead, tr_html)

return table_html
except template.VariableDoesNotExist:
return ''

Template:

{% make_table changes "Recent Changes" "updated_on,job,node,performed_command,successful" %}

Where outputs is a list of "Change" objects, "Recent Changes" is what I want the table caption to be, then a list of all the fields I want in the table.

Tagged as django , make_table templatetags
Written by Andrew Konkol on July 20th, 2012 | 0 Comments

Iterating through model attributes using assignment_tags in django 1.4 templates

Documentation: Django Assignment Tags

/project/myapp/templatetags/app_admin_tags.py:

from django import template
from myapp.models import *



@register.assignment_tag(name="object_attrs")
def object_attrs(obj):
        obj_dict ={}
        for attr in obj._meta.get_all_field_names():
           obj_dict[attr] = obj.__getattribute__(attr)
        return obj_dict

Template:

{% load app_admin_tags %}
{% for obj in objects %}
        {% object_attrs obj as obj_dict %}
        {% for key,value in obj_dict.items %}
           {{key}}: {{ value }}
        {% endfor %}
{% endfor %}
Tagged as assignment_tag , custom django
Written by Andrew Konkol on July 20th, 2012 | 0 Comments

Making Fields readonly after an object has been created in django-admin

Model:

class Command(models.Model):
        command = models.TextField(('Command(s)'))
        description = models.TextField(blank=True, null=True)
        os = models.ForeignKey(OperatingSystem)

        def __unicode__(self):
           return self.command

Admin:

class CommandAdmin(admin.ModelAdmin):
        list_display= ['command','description','os']
        readonly_fields=[]
        fields =['command','description','os']

        def get_readonly_fields(self, request, obj=None):
           if obj is None:
              '''obj has not been created yet'''
              return self.readonly_fields
           else:
              '''we already know about this object make command readonly'''
              return self.readonly_fields + ['command']

Tagged as admin , django django-admin , readonly
Written by Andrew Konkol on July 18th, 2012 | 0 Comments

Creating your own Exceptions in Python

I needed to handle errors better so I looked into creating my own exceptions.  It easy, and this is a dead simple example.

#!/usr/bin/python

class AdditionError(Exception):
        pass

x = 2
y = 'i'

try:
   print  x + y

except:
   raise AdditionError("Couldn't add x + y ")
    
 
root@echo:/home/akonkol/Code/exception# ./addition.py 
Traceback (most recent call last): 
  File "./addition.py", line 14, in 
     raise AdditionError("Couldn't add x + y ") 
__main__.AdditionError: Couldn't add x + y
Tagged as exception , python
Written by Andrew Konkol on June 20th, 2012 | 0 Comments