2010-03-12 30 views
61

Nella pagina principale del sito di amministrazione in cui compaiono modelli registrati, voglio nascondere diversi modelli che sono registrati per l'amministratore Django.Django admin, nasconde un modello

Se annullare la registrazione direttamente quelli, io non sono in grado di aggiungere nuovi record come il nuovo simbolo "+" scompare aggiungere.

Come si può fare?

risposta

87

Sulla base di x0nix's answer ho fatto alcuni esperimenti. Sembra che restituire un dict vuoto da get_model_perms escluda il modello da index.html, consentendo comunque di modificare direttamente le istanze.

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) 
+2

Nice and concise. Grazie! –

+0

concordato. Solo questo è un problema quando non voglio cambiare il codice. Quello che voglio dire è che ho un'app di base che voglio mantenere pulita dalle dipendenze su altre app. Mantengo queste dipendenze in un'app derivata dal progetto specifico. Ora voglio che l'interfaccia di amministrazione mostri solo l'app derivata, non l'app di base. Django richiede che l'app di base sia elencata nelle impostazioni/INSTALLED_APPS affinché l'app derivata funzioni. Ovviamente, l'app di base non dovrebbe mostrare, ma allo stesso tempo non voglio mantenerla inalterata e riutilizzabile. Vedi [here] ([se]/questions/13923968 /). – Sven

+5

Un modo più breve: 'get_model_perms = lambda self, req: {}' –

1

soluzione Ugly: override indice amministratore modello cioè copia index.html da Django al vostro /admin/index.html e aggiungere qualcosa di simile:

{% for for model in app.models %} 
    {% ifnotequal model.name "NameOfModelToHide" %} 
    ... 
21

avuto lo stesso problema, ecco quello che mi si avvicinò con .

Come nella precedente soluzione - copiare index.html da Django al vostro /admin/index.html e modificarlo in questo modo:

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

E creare ModelAdmin sottoclasse:

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 

Ora, qualsiasi il modello registrato con la sottoclasse HiddenModelAdmin non verrà visualizzato nell'elenco degli amministratori, ma sarà disponibile tramite il simbolo "più" in dettaglio:

class MyModelAdmin(HiddenModelAdmin): 
    ... 

admin.site.register(MyModel, MyModelAdmin) 
+0

grazie mille per la risposta! – Hellnar

+0

Semplice e facile da usare. Buona idea, amico! ;) –

+0

Questa è una soluzione molto più elegante e versatile rispetto a quella accettata – XelharK

0

Django 1.2 ha dichiarazioni if-nuovi, il che significa che la funzione desiderata potrebbe essere ottenuto solo sovrascrivendo admin/index.html

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

Questa è una cattiva soluzione, perché non si preoccupa di amministratori multi-lingua . Ovviamente potresti aggiungere i nomi dei modelli in tutte le lingue supportate. È una buona soluzione perché non sovrascrive più di un aspetto delle funzioni core di Django.

Ma prima di cambiare nulla, penso che la gente dovrebbe pensare a questo ...

In sostanza il problema è legato ad avere modelli che non si desidera utilizzare per più di aggiungere l'opzione di un menu a discesa una volta fra poco. Potrebbe essere efficacemente aggirato creando un insieme di permessi per gli utenti "non così avanzati" che vanno in panico quando ci sono troppi modelli. Nel caso in cui siano richieste modifiche nei modelli particolari, è sufficiente accedere con "account avanzato".

1

Si tratta di un edificio alternativo alla risposta superiore di x0nix, e solo se si è soddisfatti nascondere le righe con jQuery.

Copia incolla dal altra risposta la parte che ho riutilizzato

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) 

Quindi installare django-jquery e quindi aggiungere la seguente blocco nel /admin/index.html modello:

{% 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 %} 

Non è necessario copiare incollare l'intero modello, basta estenderlo e scavalcare il blocco extrahead.Avrai bisogno di django-apptemplates per il funzionamento di cui sopra.

11

Dal momento che Django 1.8, ModelAdmin ha un nuovo metodo chiamato has_module_permission() che è responsabile della visualizzazione di un modello nell'indice di amministrazione.

Per nascondere un modello dall'indice di amministrazione, è sufficiente creare questo metodo nella classe ModelAdmin e restituire False. Esempio:

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

Sfortunatamente 'has_module_permission' ha effetto sull'intera app e non solo su un modello. Quindi, aggiungendo questo a un modello nell'app, viene visualizzato il messaggio Proibito 403 nell'elenco dei modelli di app (/ admin/app_label /). Vedi [django/contrib/admin/sites.py] (https://github.com/django/django/blob/255fb992845e987ef36e3d721a77747a0b2df620/django/contrib/admin/sites.py#L401). – Fabian

+1

@Fabian Penso che sia un bug. Ho chiesto questo sul canale IRC di Django, e alcune persone sono d'accordo sul fatto che questo comportamento sia indesiderato. – xyres

+0

@Fabian Supponendo che la pagina di indice dell'amministratore rimandi ancora a _/admin/_ è possibile aggirare tale bug con qualcosa come 'return request.path! = '/ Admin /''. Sfortunatamente questo riattiva quei modelli nella lista dei modelli di app. – ecp

0

Ho avuto un sacco di amministratori modello per la registrazione e nascondere, se si desidera una soluzione più asciutto, questo ha funzionato per me (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) 

Credo che si potrebbe trasferirlo in una classe di utilità se si desidera riutilizzarlo attraverso le app.

0

A partire da Django 1.8.18, has_module_permission() ha ancora problemi. Quindi, nel nostro caso, abbiamo utilizzato anche lo get_model_perms(). Allo stesso modo, abbiamo bisogno di nascondere il modello solo per un utente specifico, ma lo superuser dovrebbe essere in grado di accedere alla sua voce di indice.

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)