Je veux afficher ManyToManyField
s dans admin, tout comme filter_horizontal
fait, mais remplir les options que l'utilisateur tape dans le champ de filtre. Il y a beaucoup d'options et les charger toutes en même temps prend beaucoup de temps.Django: AJAX ManyToManyField dans admin
J'ai trouvé django-ajax-filtered-fields mais il me semble être trop exigeant car cela nécessite des changements dans les classes de modèles, alors que tout ce que je veux faire est de remplacer chaque champ de sélection multiple dans un formulaire. Écrire un champ de widget personnalisé qui hérite de admin.widgets.FilteredSelectMultiple
semble être le bon moyen. Donc, j'essaie de rouler mon propre widget:
class MultiSelectWidget(FilteredSelectMultiple):
class Media:
# here should be some js to load options dynamically
js = (
"some_js_to_load_ajax_options.js",
)
def render_options(self, choices, selected_choices):
# this initializes the multiple select without any options
choices = [c for c in self.choices if str(c[0]) in selected_choices]
self.choices = choices
return super(MultiSelectWidget,
self).render_options([], selected_choices)
class MyAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyAdminForm, self).__init__(*args, **kwargs)
self.fields['m2m_field'].widget = MultiSelectWidget('m2m_field', is_stacked=False)
class Meta:
model = MyModel
class MyAdmin(admin.ModelAdmin):
form = MyAdminForm
qui rend correctement.
Mais je ne suis pas sûr comment implémenter cette partie ajax some_js_to_load_ajax_options.js
. Dois-je écrire mon propre extrait jQuery ou modifier SelectFilter2
qui est livré avec admin/media/js
? Quelqu'un a-t-il déjà été là?
modifier: Bien que pas lié au cœur de la question, que je ne veux remplacer le widget de champ, le chemin le plus court est d'utiliser formfield_overrides
:
class MultiSelectWidget(FilteredSelectMultiple):
# as above
class MyAdmin(admin.ModelAdmin):
formfield_overrides = {
models.ManyToManyField: {'widget': MultiSelectWidget},
}
pouvez-vous être plus précis? – omat