修改预先存在的代码中定义的类的最佳方法是使用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__
注(2019 年 8 月 27 日):
我完全了解子类化/继承的工作原理,这是解决此类问题的最佳实践。但是,正如我在下面的评论中重申的那样,子类化不会解决 OP 的问题,即。制作filter_horizontal
或filter_vertical
默认。通过子类化,您不仅需要为所有模型注册子类,还必须取消注册在内置 Django 应用程序和已安装的第三方应用程序中注册的每个 ModelAdmin 子类,然后注册新的 ModelAdmin 子类。因此,例如对于 Django 的内置用户模型...
admin.site.unregister(User)
class CustomModelAdmin(admin.ModelAdmin):
""" Add your changes here """
admin.site.register(User, CustomModelAdmin)
...然后为您安装的所有 Django 应用程序和第三方应用程序重复类似的代码。我认为这不是 OP 想要的,因此我的回答。