Use manytomany widget outside ModelAdmin

I am trying to render a form (in a custom view) in which I would like to select multiple model instances. The html created by the form is a simple select tag, which is hard to use due to the amount of choices I have.

I would like to use the widget that the ModelAdmin has to offer thanks to its “filter_horizontal” attribute. I located its js file (STATIC_ROOT + “/admin/js/SelectFilter2.js”) however I can’t seem to make it work.

I am not really competent in JQuery and the documentation about JS customization didn’t help me that much. If possible I would like to avoid using JQuery.

I have tried to add the js file to my form’s media like so :

class MyForm(forms.Form):
series = forms.ModelMultipleChoiceField(
label=“Series”,
queryset=Serie.objects.all().order_by(“name”),
widget=FilteredSelectMultiple(verbose_name=“Series”, is_stacked=False)
)
class Media:
css = {
‘all’: ‘/admin/css/widgets.css’,
}
js = (
“/admin/js/SelectFilter2.js”,
‘/admin/jsi18n’
)

but to no effect.

Can someone explain to me how to implement this widget change ?

The Select2 widget is a separate component. You can find the docs for it at https://select2.org/. It’s going to use AJAX to call a view that you’ll need to implement in the back end. (The widget alone isn’t going to work for you without that view. The Django Admin implements that view for the admin pages.) There’s also an integration package that has been created for using Select2 with Django, called appropriately enough, Django-Select2.

Thank you for your answer, I will most certainly use Django-Select2.

I don’t understand why it needs a cache server to work though. In the documentation the only part refering to this server is :

Finally make sure you have a persistent cache backend setup (NOT DummyCache or LocMemCache ), we will use Redis in this example. Make sure you have a Redis server up and running:

It doesn’t say why it needs this server. Also, can’t I use the server/view used by Django Admin ?

I don’t have an answer regarding the cache - I’m only guessing that it’s because of the number of AJAX calls being made when using that widget. You don’t want to be hitting the database for every request.

You might be able to make it work. No idea how, though. You could dig around into the Django Admin source to see how the autocomplete fields are put together and used.

I did not think they would make AJAX calls for a filter on a select, but if they do then I guess it makes sense to use cache.

I’ll dig in further and make it work using the links you provided, many thanks.

From the docs page on Data Sources:

In addition to handling <option> elements that explicitly appear in your markup, Select2 can also retrieve the results from other data sources such as a remote JSON API or a local Javascript array.

If you’ve got a large number of options, it could create a huge page, making the page very slow to create, send, and render in the browser. One of the advantages of something like Select2 is that it avoids needing to send all the options to the browser in advance. You can start typing, and it will send what you’ve typed to a defined endpoint. Since each AJAX call would be a separate request, I can understand why they’d consider a full cache to be effectively required.