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

时间:2012-01-02 03:23:55

标签: python django django-admin python-2.6 django-1.3

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

如何将filter_horizontal设置为所有ManyToManyFields的默认设置?

(当然,我对filter_vertical感到满意。)

我一直在寻找解决方案,但没有在Google或SO上找到任何内容。我可以想一想如何用一些元编程来做到这一点,但是如果有人已经这样做了,或者如果它在某个地方的Django中,我很乐意听到它。

2 个答案:

答案 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个月后回到此状态,并且在继承层次结构中找不到它时,将不胜感激。