Making admin bulk delete action work with django-mptt

For the past month and a half I have been learning Django (and therefore Python…) at my new job.

I’m very impressed how quick it has been to learn, and particularly with how complete and well thought-through the Django framework is. Python is nice too, I’m not missing all the $ signs, semi-colons and curly braces at all🙂

django-mptt works great but to properly manage an mptt model in the django admin you have to do a bit of hacking:

Following the instructions here, we borrow some code from the FeinCMS app to add tree control to the admin. See update at end of article for an extra hack you may need.

At the bottom of that article they list some extra tweaks to put ‘add child’ and ‘preview’ icons in the actions column, which are worth doing.

At this point your mptt admin is working pretty well. One problem you find is if you use the actions drop-down menu to ‘delete selected’ items from your mptt model… the bulk actions bypass the model’s delete method so your left/right values for the tree aren’t updated.

What you need is a way to rebuild the tree after a bulk action… looking around the django-mptt site you can find a patch in this thread which adds a ‘rebuild’ method to the tree manager. Go ahead and patch!

Finally we want to hack the Django admin’s default ‘delete_selected’ action so it calls the rebuild method. Once you’ve got the FeinCMS and patched django-mptt the code to pull it all together is pretty simple: http://www.djangosnippets.org/snippets/1775/

That’s it… your actual model admin class can then inherit off this one.

I’ve been loving the multiple inheritance in Python actually. I’ve found it particularly useful with the Django models and model admin classes. For example a model may have mptt tree functionality, it may also use django-tagging (another very handy app!) and the django contrib.comments app.

Each of these requires a bit of specialised admin functionality and if you have several models which use those apps, in different combinations, then you want to be able to re-use that code in a granular way. With multiple inheritance I can just say:

I like this a lot. Incidentally, if you’re using django-tagging you want to have a look at this auto-complete widget – I think it’s a good idea to use something like that to help prevent duplicate tags with slightly different spelling etc.

Update (30 Oct 09):

Something I forget, which you may need to do. After step (1) you may need to do a hack to the feincms/admin/tree_editor.py … Fein CMS assumes you use the default ‘parent’ attribute name in your mptt tree model, which works for them, but mptt gives you the possibility to change this in the model’s Meta class so we need to make the tree_editor code more generic.

I’d really like to be able to apply that change without modifying the original Fein CMS files. If anyone knows an elegant way to do so please let me know.

As a Python noob the best way I could come up with is to make my own TreeEditor class that inherits from the Fein CMS one and then override the ‘changelist_view’ method (ie copy and paste it but point it to my version of _build_tree_structure).

Update (2 Nov 09):

I sent the neccessary code change as a patch to Matthias of FeinCMS and it’s now been applied, so if you’ve got a fresh copy of the source there’s no more need to hack the tree_editor.py!