登録済みモデルが表示される管理サイトのルートページで、Django管理者に登録されているいくつかのモデルを非表示にします。
それらを直接登録解除すると、新しい記号「+」が消えて新しいレコードを追加できなくなります。
これはどのように行うことができますか?
回答:
x0nixの答えに基づいて、私はいくつかの実験を行いました。から空のdictを返すと、get_model_perms
index.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)
get_model_perms = lambda self, req: {}
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を参照してください。
return request.path!='/admin/'
ます。残念ながら、アプリモデルリストでそれらのモデルが再度有効になります。
同じ問題が発生しました。ここで私が思いついたものです。
前のソリューションと同様に、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)
醜い解決策:管理インデックステンプレートをオーバーライドします。つまり、index.htmlをdjangoから/admin/index.htmlにコピーし、次のようなものを追加します。
{% for for model in app.models %}
{% ifnotequal model.name "NameOfModelToHide" %}
...
これは、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が必要です。
Django 1.2には新しいifステートメントがあります。つまり、admin /index.htmlを上書きすることによってのみ目的の機能を取得できます。
{% if model.name not in "Name of hidden model; Name of other hidden model" %}
...
{% endif %}
多言語の管理者を気にしないので、これは悪い解決策です。もちろん、サポートされているすべての言語でモデルの名前を追加することもできます。コアDjango関数の複数の側面を上書きしないため、これは優れたソリューションです。
しかし、何かを変える前に、人々はこれについて考えるべきだと思います...
基本的に、問題は、ドロップダウンにオプションをたまに追加する以外に使用したくないモデルがあることに関連しています。モデルが多すぎるとパニックになる「それほど高度ではない」ユーザー向けの一連のアクセス許可を作成することで、効果的に回避できます。特定のモデルの変更が必要な場合は、「高度なアカウント」でログインするだけです。
登録して非表示にするモデル管理者がたくさんいました。もっと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)
アプリ間で再利用したい場合は、ユーティリティクラスにロールインできると思います。
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)