django-admin中ManyToManyFields
的默认小部件很难使用。我可以在各个字段上设置filter_horizontal
并获得更好的小部件。
如何将filter_horizontal
设置为所有ManyToManyFields
的默认设置?
(当然,我对filter_vertical
感到满意。)
我一直在寻找解决方案,但没有在Google或SO上找到任何内容。我可以想一想如何用一些元编程来做到这一点,但是如果有人已经这样做了,或者如果它在某个地方的Django中,我很乐意听到它。
答案 0 :(得分:4)
修改预先存在的代码中定义的类的最佳方法是使用mixin。您需要修改formfield_for_manytomany
类的ModelAdmin
方法;方法是defined in BaseModelAdmin
。
在Django服务器启动[[{1}}您自己的某个应用程序]中保证运行的模块中添加以下代码:
models.py
答案 1 :(得分:0)
仍然有点hacky,但是比其他答案要好,这会在Django升级期间引起各种痛苦。从此继承(不要打补丁):
class BaseAdmin(models.Admin):
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
"""
Get a form Field for a ManyToManyField. Tweak so filter_horizontal
control used by default. If raw_id or autocomplete are specified
will take precedence over this.
"""
filter_horizontal_original = self.filter_horizontal
self.filter_horizontal = (db_field.name,)
form_field = super().formfield_for_manytomany(db_field, request=None, **kwargs)
self.filter_horizontal = filter_horizontal_original
return form_field
@admin.register(AcmeModel)
class AcmeModelAdmin(BaseAdmin):
# Sub-classes can still specify raw_id, autocomplete, etc.
# That will override our filter_horizontal defaulting.
pass
出于某种原因,在filter_horizontal
中设置__init__
无效,并且没有get_filter_horizontal
可以覆盖。
如上所述,避免猴子打补丁,而只继承自BaseClass
。您,尤其是您的同事将在6个月后回到此状态,并且在继承层次结构中找不到它时,将不胜感激。