Django Tip: Custom Admin Templates

One of Django’s best assets is its extensive and very good documentation. However, there are few cases where the documentation is lacking or totally missing. Customizing the automatic admin interface is one of these cases.

In the official Django documentation there are FAQs titled How can I customize the functionality of the admin interface? and The dynamically-generated admin site is ugly! How can I change it?. What they explain, in a nutshell, is that you can use custom JavaScript to add functionality, and modify the CSS to customize how the admin looks. Latter also points to a new documentation page titled Customizing the Django admin interface. All these pages fail to mention, however, that you can customize the templates too.

Even the Django tutorial mentions the possibility of overriding the basic admin templates — just like you can do with any other app. But modifying a template admin-wide is not always enough. Wouldn’t it be great to override templates per-app basis, just like with generic views? Well, turns out you can do exactly that.

The change_list.html and change_form.html templates can be overridden on per app and per object basis. That means that you can customize a template for not only for a specific app, but for a specific model, too. This is very handy!

To override a template with your own, copy the original to your templates directory in one of these locations:

  • admin/<app_label>/<object_name>/change_form.html
  • admin/<app_label>/change_form.html
  • admin/change_form.html

The admin templates have also very flexible blocks built in so you can just extend the original template and override just the blocks you want if you don’t want to write the whole template yourself. This way you can keep the custom template code very nice and clean.

With custom templatetags and custom templates, the possibilities of customizing the Django admin interface are endless. That said, it’s also good to remember that the automatic admin is not perfect for everything. If you feel that it doesn’t quite cut it, just write your own admin views. With the newforms-library that they are cooking at the Django HQ, it’s not only easy, but truly fun.

Further reading

  • NewAdminChanges – A wiki page that explains some of the functionality in the admin app
  • /trunk/django/contrib/admin – The best way of learning things is to look inside. Browse trough the admin app code — just to see that its really just an ordinary (well, not really) Django app.


I’ve just published a new design on this blog. First version was a good start but I think that the new design brings it much closer to what I originally was looking for.

Idea for the big footer is stolen from Jeff Croft, whose site is a great demonstration of what can be accomplished with Django and some imagination. Front page is now a bit different than other pages, and comments had some loving too. The main focus has been on simplicity. And, like always, it’s far from finished.

(A note to IE users: I’m almost certain that something here breaks with your crappy browser. Frankly, I don’t care. After fighting those stupid IE bugs and other historical CSS quirks all day long for client sites, it’s very refreshing to ignore them on a personal site. So no love for your broken browser from here. Not now, not ever. Upgrade to a real browser, get a Mac, or die whining. Thank You. PS. If something breaks with Opera, OmniWeb or some other cool browser, please let me know!)

After the first release at November, there have been quite many upgrades under the hood along the way. Tags can now be viewed in a cloud and individual tag pages have related links (links with same tags) attached. There is an RSS-feed for each tag also. To be 2.0-credible, I integrated my data to a local database and pull it to the footer and (at the moment very unstyled) a dedicated music page.

The best is yet to come

This blog has become my personal sandbox for Django development. I’ve experimented with some AJAXy stuff with my own comments app and a basic inline editing proof of concept (a quicktime demo), both of which I hopefully get soon in shape for giving back to community as open source. I’m planning to write up more Django tips in the future to point out some cool but undocumented features that I’ve been playing with lately.

Trying to share data between Finnish and English parts of the site has proven to be a bit tricky. For example the links in the footer may (or may not) look odd if you can’t read Finnish. These kind of things are becoming more important in a world where people from different backgrounds meet on the Web, so I’m sure there will be some i18n topics in this blog in the future.

As always, comments and suggestions are very welcome!

Something to Think About

From Wikipedia:

The Darfur conflict is an ongoing armed conflict in the Darfur region of western Sudan, mainly between the Janjaweed, a militia group recruited from the tribes of the Abbala (camel-herding Arabs), and the non-Baggara people (mostly land-tilling tribes) of the region. The Sudanese government, while publicly denying that it supports the Janjaweed, has provided arms and assistance and has participated in joint attacks with the group, systematically targeting the Fur, Zaghawa, and Massaleit ethnic groups in Darfur. The conflict began in July 2003.

Estimated number of deaths in the conflict have ranged from 50,000 to 450,000. Most NGOs use 400,000, a figure from the Coalition for International Justice that has since been cited by the United Nations.

The mass media have described the conflict as both “ethnic cleaning” and “genocide”.

The Darfur Wall is a site where You can help. It shows 400 000 numbers, each representing one killed person in the Darfur genocide. “Donate one dollar or more to turn a number from dark gray to brilliant white and honor one lost life. 100% of the proceeds go to four Darfur relief organizations.”

Peaceful Holidays.

I Want My Preferences Online

Yet another interesting video from Google: this time it’s Guido talking about a code reviewing app that he’s been developing for Googles internal use. What’s interesting about this, is the fact that he used Djangos templates for building the UI.

During his presentation Guido mentioned a very common usability problem in modern software: it’s often very hard to use an easily configurable program on other persons computer (because it behaves very diffrently than what you are used to). In his example, Guido mentioned Emacs, I was thinking about TextMate.

I absolutely love TextMate, but I hate the fact that when I’m using it on somebody elses computer, it feels like using a totally different program. And it’s not just text editors. Nowadays, I find it very hard to use Mac OS X withouth QuickSilver. And what can you do with QuickSilver that is not trained to do exactly the things that you want? Not very much. This problem of adaptive software is quite universal.

This is hardly news to anobody. Usability people haven been talking about this for years, but why is it that nobody haven’t come up with any decent solution for it yet? Come on, it’s not like we’re living in eighties anymore. We have this web 2.0 thingy with the tubes and all.

Give me a way to use my TextMate with my own settings and preferences from any computer. Well, at least on any computer running on Mac OS X 🙂

Spare Me From Choices

I found a great presentation from Google Video about why too many choices is a bad thing. I couldn’t agree more. (Even this blog is named Too Many Choices 🙂 For me, Django (and Python) is about making less (and therefore better) choices.

Many web frameworks boast with the fact that they offer infinite choice of solutions for every possible problem. Whether the choice is about object-relational mapping, templating or whatever, more choices means added burden to the developer to choose the right one. With Rails less choice is “opinionated software“. With Django, it’s consistency, cohesion and perfectionism.

I love that fact that there is just one way of doing things (right). It’s easy to remember, it makes writing code faster, and it helps reading other peoples code.

For a much more better view on the paradox of choice, listen to this presentation given by Professor Barry Schwartz, April 2006. (There’s not very much visual info in the video. Just hit play and listen.)