Django Aware

« | Home | »

Adding Custom Actions To Django Admin Change Forms

By Paul Kenjora | November 7, 2007

I recently had a problem where I needed to add a custom action next to "History" and "View on site" in the Django admin change form for a specific model. Normally I would overload the admin template. Problem is I wanted to retain "History" and "View". The approach I took was to extend the model interface just like "search_fields" and "list_filter". This required surprisingly little modification of the framework as I followed mostly the models already there. To my surprise the pieces fit really nicely, existing "History" and "View" links work pretty much the same way, I just defined a customizable list. I implemented in 0.95 but it works just as well in 0.96 and up.

What is It

In short the ability to add any action to the top of any admin change form that links to a custom URL of your choosing, it even passes the model and object id. You could use this for things like "Email To Admin" or "Scrape From Some Place". Typically I envision short scripts that refresh or distribute the object to third parties and then return back to the editing page.

Model Interface

Custom actions are added though the model definition. To create a custom action simply add it to the list "form_actions". The action consists of a URL tag, in this case "email", which is used in the redirect and a label, in this case "Email HR". A complete example below…

Custom Action Handlers

The handler for a custom action can be any regular Django URL handler as defined in "urls.py". No fear, this is business as usual, just make sure to define a URL pattern according to "admin/[tag]/\d+/(?P\d+)/$" where [tag] was given in the model.

Technically thats all you need to do if you want to use this feature. Now implementing it is almost as easy. If only someone added this to the official branch…sigh. Expect this to take 10 minutes and work the first time, seriously its that easy…

Modifying Django Admin

First define the special "tag" and "label" class. Technically this could be a tuple of strings…next version. Simply add it to the admin models.

Django-0.95/django/contrib/admin/models.py

Follow that up with a one line change to the view handler for admin change forms. The code below is the whole function for reference but only the line "’form_actions’: opts.admin.form_actions" needs to be added. It just sends the new values from the model to the context.

Django-0.95/django/contrib/admin/views/main.py

The last change is to add one line to the template to use the new form lists. Modify the change form template, yes you could override it but you already made changes to the admin code. Again the code below is a reference, the only thing to add is the "for loop" line.

Django-0.95/django/contrib/admin/templates/admin/change_form.html

Conclusion

Thats it, now any model can add custom actions to your change forms. in the future the custom class could go away and be replaced by a simple string tuple. Other than that this code is non intrusive, inline with the admin model to date, and super handy when needed. I do wake up with cold sweats imagining that I did something that already exists and is easily handled in a complex and redundant way but so far no one has pinted out a cleaner alternative. Big thanks to the boys at Django for putting together an awesome framework that makes this possible.

Topics: Admin Revisions, Model Revisions | Comments

  • Hugo
    I am using django 0.96, and try to follow your steps. But when I run 'python manage.py runserver' I got an error. The error is:

    diagramacao.conteudo: Error when calling the metaclass bases
    __init__() got an unexpected keyword argument 'form_actions'

    Can you help me?
  • ChaosKCW
    Excellent Article, just what i was looking for! Any sign of inclusion in the trunk ?
blog comments powered by Disqus