Django管理者、モデルを非表示


85

登録済みモデルが表示される管理サイトのルートページで、Django管理者に登録されているいくつかのモデルを非表示にします。

それらを直接登録解除すると、新しい記号「+」が消えて新しいレコードを追加できなくなります。

これはどのように行うことができますか?

回答:


123

x0nixの答えに基づいて、私はいくつかの実験を行いました。から空のdictを返すと、get_model_permsindex.htmlからモデルが除外されますが、インスタンスを直接編集できるようになります。

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        """
        Return empty perms dict thus hiding the model from admin index.
        """
        return {}

admin.site.register(MyModel, MyModelAdmin)

同意しました。コードを変更したくない場合にのみ問題になります。つまり、他のアプリへの依存からクリーンに保ちたいベースアプリがあります。これらの依存関係は、派生したプロジェクト固有のアプリに保持します。ここで、管理インターフェースに、ベースアプリではなく、派生アプリのみを表示するようにします。Djangoでは、派生アプリが機能するために、ベースアプリがsettings / INSTALLED_APPSにリストされている必要があります。明らかに、ベースアプリは表示されるべきではありませんが、同時に、変更せずに再利用できるようにしたくありません。[こちら](Stack Exchange / questions / 13923968 /)を参照してください。
スヴェン

6
短い方法:get_model_perms = lambda self, req: {}
Tigran Saluev 2013

2
特定のuserAdminからモデルを非表示にしたい場合はどうすればよいですか?
Alireza Sanaee 2014

この解決策には注意してください-リンクが消えても、ユーザーは次のようにオブジェクト自体にジャンプできます:/ admin / main / comment / 2333 / change /
goodgrief

31

Django1.8以降の場合

Django 1.8以降、adminインデックスにモデルを表示するためのModelAdmin新しいメソッドが呼び出されましhas_module_permission()た。

管理インデックスからモデルを非表示にするには、ModelAdminクラスでこのメソッドを作成して、を返しFalseます。例:

class MyModelAdmin(admin.ModelAdmin):
    ...
    def has_module_permission(self, request):
        return False

残念ながらhas_module_permission、1つのモデルだけでなく、アプリ全体に影響します。したがって、これをアプリのモデルに追加すると、アプリモデルリスト(/ admin / app_label /)で403Forbiddenが発生します。django / contrib / admin /sites.pyを参照してください。
ファビアン2016

1
@Fabianそれはバグだと思います。私はDjangoのIRCチャネルでこれを尋ねましたが、この動作が望ましくないことに同意する人もいます。
xyres 2016

@Fabian管理者インデックスページがまだ/ admin /にリンクしていると仮定すると、のような方法でそのバグを回避することができreturn request.path!='/admin/'ます。残念ながら、アプリモデルリストでそれらのモデルが再度有効になります。
ecp 2016

私はこのバグのチケットをここで開いていました。これはここで修正れました。うまくいけば、次のリリースに含まれるはずです。
xyres 2016

Django 1.11では、ディープリンクは引き続き機能しますが、エンティティはメインの管理画面に表示されません
CsabaToth19年

22

同じ問題が発生しました。ここで私が思いついたものです。

前のソリューションと同様に、index.htmlをdjangoから/admin/index.htmlにコピーし、次のように変更します。

{% for model in app.models %}
    {% if not model.perms.list_hide %}
    <tr>
    ...
    </tr>
    {% endif %}
{% endfor %}

そして、ModelAdminサブクラスを作成します。

class HiddenModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, *args, **kwargs):
        perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
        perms['list_hide'] = True
        return perms

これで、HiddenModelAdminサブクラスに登録されたモデルは管理者リストに表示されなくなりますが、「プラス」記号で詳細に利用できるようになります。

class MyModelAdmin(HiddenModelAdmin):
    ...

admin.site.register(MyModel, MyModelAdmin)


1

これは、x0nixの答えに基づいた代替の構築であり、jqueryで行を非表示にすることに満足している場合に限ります。

再利用した部分を他の回答からコピー&ペースト

class HiddenModelAdmin(admin.ModelAdmin):
def get_model_perms(self, *args, **kwargs):
    perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
    perms['list_hide'] = True
    return perms

class MyModelAdmin(HiddenModelAdmin):
...

admin.site.register(MyModel, MyModelAdmin)

次に、django-jqueryをインストールしてから、/admin/index.htmlテンプレートに次のブロックを追加します。

{% extends "admin:admin/index.html" %}

{% block extrahead %}
    <script type="text/javascript" src="{{ STATIC_URL }}js/jquery.js"></script>
    {% if app_list %}
      <script type="text/javascript">
        $(function(){
          {% for app in app_list %}
            {% for model in app.models %}
                {% if model.perms.list_hide %}
                    $('div.app-{{ app.app_label }}').find('tr.model-{{ model.object_name|lower }}').hide();
                {% endif %}
            {% endfor %}
          {% endfor %}
        });
     </script>
   {% endif %}
{% endblock %}

テンプレート全体をコピーして貼り付ける必要はありません。テンプレートを拡張してextraheadブロックを上書きするだけです。上記を機能させるには、django-apptemplatesが必要です。


0

Django 1.2には新しいifステートメントがあります。つまり、admin /index.htmlを上書きすることによってのみ目的の機能を取得できます。

{% if model.name not in "Name of hidden model; Name of other hidden model" %}
    ...
{% endif %}

多言語の管理者を気にしないので、これは悪い解決策です。もちろん、サポートされているすべての言語でモデルの名前を追加することもできます。コアDjango関数の複数の側面を上書きしないため、これは優れたソリューションです。

しかし、何かを変える前に、人々はこれについて考えるべきだと思います...

基本的に、問題は、ドロップダウンにオプションをたまに追加する以外に使用したくないモデルがあることに関連しています。モデルが多すぎるとパニックになる「それほど高度ではない」ユーザー向けの一連のアクセス許可を作成することで、効果的に回避できます。特定のモデルの変更が必要な場合は、「高度なアカウント」でログインするだけです。


0

登録して非表示にするモデル管理者がたくさんいました。もっとDRYソリューションが必要な場合は、これでうまくいきました(Django 1.10、Python 3.5)

# admin.py

def register_hidden_models(*model_names):
    for m in model_names:
        ma = type(
            str(m)+'Admin',
            (admin.ModelAdmin,),
            {
                'get_model_perms': lambda self, request: {}
            })
        admin.site.register(m, ma)

register_hidden_models(MyModel1, MyModel2, MyModel3)

アプリ間で再利用したい場合は、ユーティリティクラスにロールインできると思います。


0

Django 1.8.18の時点では、has_module_permission()まだ問題があります。したがって、この場合は、も使用しましたget_model_perms()。同様に、特定のユーザーに対してのみモデルを非表示にする必要がありますが、superuserはそのインデックスエントリにアクセスできる必要があります。

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        if not request.user.is_superuser:
            return {}
        return super(MyModelAdmin, self).get_model_perms(request)

admin.site.register(MyModel, MyModelAdmin)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.