Django: AJAX ManyToManyField en admin
Quiero mostrarManyToManyField
s en admin al igual quefilter_horizontal
lo hace, pero completa las opciones a medida que el usuario escribe en el campo de filtro. Hay muchas opciones y cargarlas todas a la vez lleva mucho tiempo.
encontrédjango-ajax-filter-fields pero me parece una exageración ya que requiere cambios en las clases de modelos, cuando todo lo que quiero hacer es reemplazar cada campo de selección múltiple en un formulario.
Escribir un campo de widget personalizado que herede deadmin.widgets.FilteredSelectMultiple
Parece ser el camino correcto. Así que estoy tratando de rodar mi propio 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
que se procesa correctamente.
Pero no estoy seguro de cómo implementar estosome_js_to_load_ajax_options.js
parte ajax. ¿Debo escribir mi propio fragmento de jQuery o modificarlo?SelectFilter2
que viene conadmin/media/js
? ¿Alguien ha estado allí antes?
editar: Aunque no está relacionado con el núcleo de la pregunta, ya que solo quiero anular el widget del campo, la forma más corta es usarformfield_overrides
:
class MultiSelectWidget(FilteredSelectMultiple):
# as above
class MyAdmin(admin.ModelAdmin):
formfield_overrides = {
models.ManyToManyField: {'widget': MultiSelectWidget},
}