Na stronie głównej serwisu administracyjnego, gdzie pojawiają się zarejestrowane modele, chcę ukryć kilka modeli, które są zarejestrowane dla administratora Django.
Jeśli wyrejestruję je bezpośrednio, nie będę w stanie dodawać nowych rekordów, ponieważ znika symbol dodawania nowego znaku „+”.
Jak można to zrobić?
django
django-admin
Hellnar
źródło
źródło
get_model_perms = lambda self, req: {}
Dla Django 1.8 i nowszych
Od Django 1.8
ModelAdmin
ma nową metodę o nazwie,has_module_permission()
która jest odpowiedzialna za wyświetlanie modelu w indeksie administratora.Aby ukryć model przed indeksem administratora, po prostu utwórz tę metodę w swojej
ModelAdmin
klasie i zwróćFalse
. Przykład:class MyModelAdmin(admin.ModelAdmin): ... def has_module_permission(self, request): return False
źródło
has_module_permission
wpływa na całą aplikację, a nie tylko na jeden model. Więc dodanie tego do modelu w aplikacji powoduje 403 zabronione na liście modeli aplikacji (/ admin / app_label /). Zobacz django / contrib / admin / sites.py .return request.path!='/admin/'
. Niestety, powoduje to ponowne włączenie tych modeli na liście modeli aplikacji.Mam ten sam problem, oto co wymyśliłem.
Podobnie jak w poprzednim rozwiązaniu - skopiuj index.html z django do swojego /admin/index.html i zmodyfikuj go w ten sposób:
{% for model in app.models %} {% if not model.perms.list_hide %} <tr> ... </tr> {% endif %} {% endfor %}
I utwórz podklasę 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
Teraz żaden model zarejestrowany w podklasie HiddenModelAdmin nie pojawi się na liście administratorów, ale będzie dostępny szczegółowo za pośrednictwem symbolu „plus”:
class MyModelAdmin(HiddenModelAdmin): ... admin.site.register(MyModel, MyModelAdmin)
źródło
Brzydkie rozwiązanie: zastąp szablon indeksu administratora, tj. Skopiuj index.html z django do swojego /admin/index.html i dodaj coś takiego:
{% for for model in app.models %} {% ifnotequal model.name "NameOfModelToHide" %} ...
źródło
Jest to alternatywny sposób budowania na podstawie odpowiedzi x0nix i tylko wtedy, gdy z przyjemnością ukryjesz wiersze za pomocą jquery.
Skopiuj wklejanie z drugiej odpowiedzi część, której ponownie użyłem
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)
Następnie zainstaluj django-jquery, a następnie dodaj następujący blok do swojego
/admin/index.html
szablonu:{% 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 %}
Nie musisz kopiować, wklejać całego szablonu, po prostu rozszerz go i nadpisuj
extrahead
blok. Będziesz potrzebować szablonów django-apptemplates, aby powyższe działało.źródło
Django 1.2 ma nowe instrukcje if, co oznacza, że żądaną funkcję można uzyskać tylko przez nadpisanie admin / index.html
{% if model.name not in "Name of hidden model; Name of other hidden model" %} ... {% endif %}
To złe rozwiązanie, ponieważ nie dba o wielojęzycznych administratorów. Możesz oczywiście dodać nazwy modeli we wszystkich obsługiwanych językach. To dobre rozwiązanie, ponieważ nie zastępuje więcej niż jednego aspektu podstawowych funkcji Django.
Ale zanim cokolwiek zmienię, myślę, że ludzie powinni o tym pomyśleć ...
Zasadniczo problem jest związany z posiadaniem modeli, których nie chce się używać na dłużej niż dodawanie opcji do listy rozwijanej od czasu do czasu. Można to skutecznie obejść, tworząc zestaw uprawnień dla „niezbyt zaawansowanych” użytkowników, którzy wpadają w panikę, gdy jest zbyt wiele modeli. W przypadku konieczności wprowadzenia zmian w poszczególnych modelach wystarczy zalogować się na „konto zaawansowane”.
źródło
Miałem wielu administratorów modelu do zarejestrowania i ukrycia, jeśli chcesz bardziej SUCHEGO rozwiązania, to zadziałało dla mnie (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)
Myślę, że możesz przekształcić go w klasę użytkową, jeśli chcesz ponownie użyć go w różnych aplikacjach.
źródło
Jak Django 1.8.18 ,
has_module_permission()
wciąż ma problem. Tak więc w naszym przypadku użyliśmy równieżget_model_perms()
. Podobnie, musimy ukryć model tylko dla określonego użytkownika, alesuperuser
powinien on mieć dostęp do swojego wpisu indeksu.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)
źródło