Friday, October 16, 2009

Neat Django Admin Tricks (Part 1)

About django admin in a sec. First a bit of setup:

As I've been organizing our office into using an issue tracker for keeping track of our Django app, I haven't really found one that 'fit' yet. The issue trackers I looked at had 1 of 2 problems:

  1. They were massive, huge, enterprise-level monsters. I need something for 3-4 people.
  2. They required a bunch of extra setup. I already have a Django app running, why load the server with extra software?
So I spent a few hours after work putting a simple issue tracker together. To really improve the usability and get what I wanted out of the app, I needed to control how the django admin was presenting things. Some neat django admin tricks were in order.

Making An Admin list_display Field Show In Color
By default, all values in the Django admin model list view are in black.

Photobucket

Boring black. If you have an issue tracker it should show in color, right? Here's what my issue admin was looking like:
class IssueAdmin(admin.ModelAdmin):
list_display = ('title', 'priority', 'completed', 'assigned_to', 'last_modified')
The easiest way to get the 'priority' column in color would be to render it as HTML. If you were to try this, you'd find that the Django admin does not escape that value, and you'd end up with < >'s showing. However, there is an API to get around that. In Python all functions are objects. Because of this, we can add a property '.allow_tags' at runtime to signal to Django that the value contains tags.
# models.py
def priority_html(self):
return u'<span >%s</span>' % self.get_priority_display()
priority_html.allow_tags = True
Our value now shows in color, but the column header renders as "Priority html". We can add one more property 'short_description' which would allow us to specify the equivalent of 'verbose_name' for a field.

Here's the (almost) complete code to achieve a custom HTML value in a list_display entry:
# models.py
class Issue(models.Model):

PRIORITY_CHOICES = (
(1, 'Low'),
(2, 'Normal'),
(3, 'High'),
)

priority = models.IntegerField(choices=PRIORITY_CHOICES, help_text='Default: Normal Priority', default=2)

def priority_html(self):
if self.priority == 3:
color = "652D90"
elif self.priority == 2:
color = "37B34A"
else:
color = "26A9E0"
return u'<span style="color:#%s">%s</span>' % (color, self.get_priority_display())
priority_html.allow_tags = True
priority_html.short_description = 'priority'

# admin.py
class IssueAdmin(admin.ModelAdmin):
list_display = ('title', 'priority_html', 'completed', 'assigned_to', 'last_modified')


Photobucket

Given the code above, I bet you can guess how the (Email) link was achieved.

1 comments:

Larry Kubin

Thanks, this really helped me make my admin listing look how I wanted it to! I was looking everywhere for how to do this.

  © Blogger template 'Minimalist G' by Ourblogtemplates.com 2008

Back to TOP