More django-mptt goodness: FilteredSelectMultiple m2m widget
November 5, 2009 6 Comments
If you are using django-mptt to manage content (eg heirarchical categories) then it needs a bit of help to make a nice admin interface. For many-to-many fields, Django provides the quite nice FilteredSelectMultiple widget (a two-pane selection list with search box) but it only renders ‘flat’ lists… if you have a big category tree it’s going to be confusing to know what belongs to what. Also, list items are sorted alphabetically by the js, which won’t be what you want.
In this post I’ll be extending FilteredSelectMultiple to show the tree structure in the list:

The code is pretty clean – no patches to hack! – and you can get it here on Django snippets.
You’ll also need to put this javascript file on your media path: mptt_m2m_selectbox.js
Once you’ve got those, you just need to use it in your admin form:
class ProductForm(forms.ModelForm):
categories = MPTTModelMultipleChoiceField(
ProductCategory.objects.all(),
widget = MPTTFilteredSelectMultiple("Categories",False,attrs={'rows':'10'})
)
class Meta:
model= ProductCategory
class ProductAdmin(admin.ModelAdmin):
form = ProductForm
And that’s about it. You could go further of course, for example by rendering the select list in a fixed-width font you could draw the tree branches in ascii. Probably it would also be useful to show a different representation in the right-hand list (eg to represent the parents of selected categories somehow).
If you make any enhancements or find any bugs then please comment back!
Thanks, just what i looking for !
Work well
Awesome! still works in Django==1.4, after a little adjustment in the js Media of widgets.py:
class Media:
extend = False
js = (settings.STATIC_URL + “admin/js/core.js”,
settings.STATIC_URL + “js/mptt_m2m_selectbox.js”,
settings.STATIC_URL + “admin/js/SelectFilter2.js”,
)
cool, thanks for the update!
I really like this! I’ve adopted it to work in a form outside of admin by calling jquery.init. But I’ve noticed in my html, the optgroup label doesn’t get injected. I believe we need optgroup to make the tree collapsable? Is that possible in the filtered select multiple widget? Thanks!
If a parent category is selected, does clicking the right arrow automatically select all the children categories into the chosen categories box on the right?
No it doesn’t, for my case that was not needed as the selection on the right represents the value I want saved in the db (the id of the parent) and the sub-categories are implicitly included by the heirarchical structure.