More django-mptt goodness: FilteredSelectMultiple m2m widget

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:

mptt FilteredSelectMultiple widget screenshot

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(
                    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!

About anentropic
songwriter, musician, and er web programmer...

6 Responses to More django-mptt goodness: FilteredSelectMultiple m2m widget

  1. Maxime says:

    Thanks, just what i looking for !
    Work well😉

  2. Michael van de Waeter says:

    Awesome! still works in Django==1.4, after a little adjustment in the js Media of

    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”,

  3. Alex says:

    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!

  4. Ronald says:

    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?

    • anentropic says:

      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.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: