在django-admin中,如何将filter_horizo​​ntal设置为默认值?

Jer*_*aum 5 python django python-2.6 django-admin django-1.3

ManyToManyFieldsdjango-admin中的默认小部件很难使用。我可以filter_horizontal在各个字段上设置并获得一个更好的小部件。

如何设置filter_horizontal所有默认值ManyToManyFields

(我当然也很高兴filter_vertical。)

我一直在寻找解决方案,但在Google或SO上却找不到任何东西。我可以考虑如何通过一些元编程来做到这一点,但是如果有人已经做到这一点,或者如果它在Django的某个地方,我很想听听它。

Sim*_*gwi 3

修改现有代码中定义的类的最佳方法是使用mixin。需要修改类formfield_for_manytomany的方法ModelAdmin;该方法定义在BaseModelAdmin.

将以下代码添加到保证在 Django 服务器启动时运行的模块(models.py您自己的应用程序之一):

from django.contrib.admin.options import ModelAdmin
from django.contrib.admin import widgets
class CustomModelAdmin:
    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        """
        Get a form Field for a ManyToManyField.
        """
        # If it uses an intermediary model that isn't auto created, don't show
        # a field in admin.
        if not db_field.rel.through._meta.auto_created:
            return None
        db = kwargs.get('using')

        if db_field.name in self.raw_id_fields:
            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db)
            kwargs['help_text'] = ''
        else:
            kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, False) # change second argument to True for filter_vertical

        return db_field.formfield(**kwargs)

ModelAdmin.__bases__ = (CustomModelAdmin,) + ModelAdmin.__bases__
Run Code Online (Sandbox Code Playgroud)

注(2019 年 8 月 27 日):

我完全了解子类化/继承的工作原理,这是解决此类问题的最佳实践。然而,正如我在下面的评论中重申的那样,子类化不会解决OP的问题,如所述。还是默认filter_horizontal的。通过子类化,您不仅需要为所有模型注册子类,还必须取消注册在内置 Django 应用程序和已安装的第三方应用程序中注册的每个 ModelAdmin 子类,然后注册新的 ModelAdmin 子类。例如,对于 Django 的内置用户模型......filter_vertical

admin.site.unregister(User)
class CustomModelAdmin(admin.ModelAdmin):
    """ Add your changes here """
admin.site.register(User, CustomModelAdmin)
Run Code Online (Sandbox Code Playgroud)

...然后对您安装的所有 Django 应用程序和第三方应用程序重复类似的代码。我认为这不是OP想要的,因此我的回答。