[Fixed]-Overriding Size of Django Admin Multi-select Widget

22👍

I did this in the admin.py by setting a blanket size for all ManyToManyField items, for instance:

from django.contrib import admin
from django.forms import SelectMultiple
from django.db import models
from models import *

class RiverAdmin(admin.ModelAdmin):
    formfield_overrides = { models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'10'})}, }

admin.site.register(River, RiverAdmin)

16👍

If you have a long select that will keep growing, I recommend to use an autocomplete widget.

Anyway, you could:

  1. Create a ModelForm, for the model in question

  2. Override the default widget, for the field in question,

  3. Set widget’s size attribute to your needs

  4. Enable that form in ModelAdmin, for example

    class YourModelForm(forms.ModelForm):
        class Meta:
            model = YourModel
            widgets = {
                'your_field': forms.SelectMultiple(attrs={'size': 12})
            }
    
    
    class YourModelAdmin(admin.ModelAdmin):
        form = YourModelForm
    
👤jpic

2👍

There is a way to do it, is to override the formfield_for_manytomany to set the size attribute.

def formfield_for_manytomany(self, db_field, request, **kwargs):
        form_field = super().formfield_for_manytomany(db_field, request, **kwargs)
        if db_field.name in [*self.filter_horizontal]:
            form_field.widget.attrs={'size': '10'}
        return form_field

0👍

I was able to make number of rows according to initial number of related table rows, however it does not updates dynamically (probably need to insert Javascript into admin form and query number of rows via AJAX, that would be too big to post here).

class ProfileAdminForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = '__all__'
        widgets = {
            # Will dynamically change number of rows in select multiple, however only after server reload.
            'spec_profiles': forms.SelectMultiple(attrs={'size': SpecProfile.objects.count()})
        }

class ProfileAdmin(admin.ModelAdmin):
    form = ProfileAdminForm

Leave a comment