Using the FilterSelectMultiple Widget

I will soon be starting a new project at work, and one of the mockups calls for a side by side control to select multiple choices in a many-to-many relationships.  The default control used by Django is the SelectMultiple widget.

 

However, this can get unwieldy when the number of choices grows.  Instead, I wish to use a filter select, as seen in the Django admin when assigning permissions to a user or group.

 

It didn’t take too much research to find a Django snippet as an example.  http://djangosnippets.org/snippets/2466/.  I pretty much copied his example, except for the CSS file called ‘uid -manage-form.css’.  This must be part of his application, because I couldn’t find any other reference to it online.

Here is the form code I ended up with:

from django.contrib.admin.widgets import FilteredSelectMultiple

class BookForm(ModelForm):
    authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all(),
                                          label=('Select Authors'),
                                          widget=FilteredSelectMultiple(
                                                    ('authors'),
                                                    False,
                                                 ))
    class Media:
        css = {
            'all':('/media/css/widgets.css',),
        }
        # jsi18n is required by the widget
        js = ('/admin/jsi18n/',)

    class Meta:
        model = Book

As the example shows, I included the tag for the form media in the <head> section of the template, which inserts the CSS and JS calls.

<head>
    ...
    {{ bookform.media }}
</head>

Once my designer gets a hold of this, I’m sure it will look great.

UPDATE: For an example of using the RelatedFieldWidgetWrapper to include the capability to add a new record, see this post.