2012-01-02 10 views
4

django-adminのManyToManyFieldsのデフォルトのウィジェットは使いにくいです。私は個々のフィールドにfilter_horizontalを設定し、ずっと良いウィジェットを得ることができます。django-adminでは、filter_horizo​​ntalをどのようにデフォルトに設定できますか?

filter_horizontalをすべてデフォルトのManyToManyFieldsに設定するにはどうすればよいですか?

(私ももちろんfilter_verticalと幸せになると思います。)

私は解決策のために周りに検索したとGoogle上またはSO何かを見つけることができませんでした。私はいくつかのメタプログラミングを使ってこれを行う方法を考えることができますが、誰かがすでにこれを行った場合、またはDjangoのどこかにいる場合は、それについて聞きたいです。

答えて

4

既存のコードで定義されているクラスを変更する最も良い方法は、mixinを使用することです。 formfield_for_manytomanyメソッドをModelAdminクラスに変更する必要があります。方法はdefined in BaseModelAdminです。あなたのDjangoのサーバーの起動時に

が実行されることが保証だモジュールで[独自のアプリケーションの1の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__ 
+0

理由だけではなく、単一継承でこれをしませんか?または実際には、 '__bases__ 'のような魔法のプロパティを使って猿を払うのではなく、複数の継承? – Marcin

+0

あなたが何を意味しているのかを説明したり、回答を投稿して自分の解決策を提案してください。私が自分自身で理解していることは、OPは、このようなフィールドを持つモデルごとに 'ModelAdmin'サブクラスを作成せずに、' ManyToManyField'で 'filter_horizo​​ntal'を使用することを望んでいるということです。 –

+0

私のコメントのどの部分が不明ですか?唯一明らかになっていないのは、継承を使用するのではなく、ライブラリクラスをサルでパッチすることを提案している理由です。 – Marcin

関連する問題