A Better Django Admin ManyToMany Field Widget

JavascriptDjangoDjango AdminHtml Select

Javascript Problem Overview


I find the the Django Admin's default models.ManyToManyField widget to be cumbersome to use. It's the HTML select element and if you have a lot of Objects of the "other" model then it's quite impractical to actually find the "other" Objects you want to associate with "this" Object. And if you have a lot of objects of the "other" model it seems to even slows down the rendering of the Admin page.

I'm aware that I can build my own custom admin widget and apply it to my ManyToManyFields as I see fit, but are there any pre-built ones out there that I might use instead? In my dreams, I picture an auto-completing text input HTML widget. Is this even practical/possible to do in the Django admin framework?

Thanks.

Javascript Solutions


Solution 1 - Javascript

Try using the filter_horizontal attribute on your admin class, for example:

class SomeModelAdmin(admin.ModelAdmin):
    filter_horizontal = ('users',)

As mentioned in the documentation, "adding a ManyToManyField to this list will instead use a nifty unobtrusive JavaScript "filter" interface that allows searching within the options". filter_vertical does the same thing with a slightly different layout.

Solution 2 - Javascript

you could try using a raw id in the admin. and the django docs: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.raw_id_fields

if you are looking for something with auto-complete you might want to look at this as a starting point http://code.djangoproject.com/wiki/AutoCompleteSolutions

and finally a very simplistic inline Example:

models.py

class SomeModel(models.Model):
    users = models.ManyToMany(User)

admin.py:

class SomeModelAdmin(admin.ModelAdmin):
    raw_id_fields = ("users",)

Solution 3 - Javascript

I haven't actually played with it but I found this promising looking library referenced elsewhere.

It appears to do exactly what I wanted. Rather than loading the entire list of related objects (regardless of how many there are!) and presenting you with a picker to select a few of them, as filter_horizontal does, it presents a search/filter box and uses typeahead/autocomplete calls to retrieve results dynamically. This is great for the case where you have maybe 5000 users and want to pick 3 or 4 of them without waiting for 5k <option> elements to download and render.

Solution 4 - Javascript

This is an old question, but I want to add an answer here for people who find this just like I did: this situation is exactly what Django inline admins are for. Specifically, I use TabularInlines with raw id fields for many-to-many relations that have too many choices.

https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.TabularInline

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChris W.View Question on Stackoverflow
Solution 1 - JavascriptBlairView Answer on Stackoverflow
Solution 2 - JavascriptmrfunyonView Answer on Stackoverflow
Solution 3 - JavascriptCodererView Answer on Stackoverflow
Solution 4 - JavascriptkloddantView Answer on Stackoverflow