Newbie Django question: I\'d like the Django admin to display more rows of choices in the multi-select widget. I have an extremely long list to select from and the default 4
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
If you have a long select that will keep growing, I recommend to use an autocomplete widget.
Anyway, you could:
Create a ModelForm, for the model in question
Override the default widget, for the field in question,
Set widget's size attribute to your needs
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
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)
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