Django:管理员中的AJAX ManyToManyField

oma*_*mat 5 django ajax django-admin manytomanyfield

我想像ManyToManyField管理员一样在管理员中显示s filter_horizontal,但是当用户键入过滤器字段时填充选项.有很多选项,一次加载它们需要花费很多时间.

我找到了django-ajax-filtered-fields,但在我看来它是一种矫枉过正,因为它需要更改模型类,当我想要做的就是替换表单中的每个多个select字段.

编写继承的自定义窗口小部件字段admin.widgets.FilteredSelectMultiple似乎是正确的方法.所以我试图推出自己的小部件:

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
Run Code Online (Sandbox Code Playgroud)

哪个渲染正确.

但我不知道如何实现这个some_js_to_load_ajax_options.jsajax部分.我应该编写自己的jQuery片段或修改SelectFilter2哪些附带admin/media/js?以前有人去过吗?

编辑: 虽然与问题的核心无关,因为我只想覆盖字段的小部件,更短的方法是使用formfield_overrides:

class MultiSelectWidget(FilteredSelectMultiple):
    # as above

class MyAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.ManyToManyField: {'widget': MultiSelectWidget},
    }
Run Code Online (Sandbox Code Playgroud)

lee*_*ech 0

我会破解选择过滤器,它有一组很好的功能可供您使用。