2010-03-12 23 views
61

En la página raíz del sitio de administración donde aparecen los modelos registrados, quiero ocultar varios modelos que están registrados en el administrador de Django.administrador de Django, ocultar un modelo

Si los anulo directamente, no puedo agregar nuevos registros ya que el símbolo agregar nuevo "+" desaparece.

¿Cómo se puede hacer esto?

Respuesta

87

Basado en x0nix's answer Hice algunos experimentos. Parece que devolver un dict vacío de get_model_perms excluye el modelo de index.html, al tiempo que le permite editar instancias directamente.

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

Agradable y conciso. ¡Gracias! –

+0

De acuerdo. Solo que eso es un problema cuando no quiero cambiar el código. Lo que quiero decir es que tengo una aplicación base que quiero mantener limpia de las dependencias de otras aplicaciones. Guardo estas dependencias en una aplicación derivada de proyecto específico. Ahora quiero que la interfaz de administrador solo muestre la aplicación derivada, no la aplicación base. Django requiere que la aplicación base aparezca en la configuración/INSTALLED_APPS para que funcione la aplicación derivada. Obviamente, la aplicación base no debería mostrarse, pero al mismo tiempo no quiero mantenerla sin modificaciones y reutilizable. Vea [aquí] ([se]/questions/13923968 /). – Sven

+5

Una forma más corta: 'get_model_perms = lambda self, req: {}' –

1

solución feo: override índice del administrador plantilla es decir, copia index.html de Django para su /admin/index.html y añadir algo como esto:

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

dieron el mismo problema, aquí lo que se le ocurrió .

Al igual que en la solución anterior - copiar index.html de Django para su /admin/index.html y modificar así:

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

Y crear ModelAdmin subclase:

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 

Ahora, cualquier modelo registrado con la subclase HiddenModelAdmin no aparecerá en la lista de administración, pero estará disponible en el símbolo "más" en detalle:

class MyModelAdmin(HiddenModelAdmin): 
    ... 

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

muchas gracias por la respuesta! – Hellnar

+0

Simple y fácil de usar. Buena idea hombre! ;) –

+0

Esta es una solución mucho más elegante y versátil que la aceptada – XelharK

0

Django 1.2 cuenta con nuevas declaraciones si-, lo que significa que la función deseada sólo podía obtenerse mediante la sobreescritura admin/index.html

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

Ésta es una mala solución, ya que no se preocupa por los administradores de múltiples idiomas . Por supuesto, puede agregar los nombres de los modelos en todos los idiomas admitidos. Es una buena solución porque no sobrescribe más de un aspecto de las funciones básicas de Django.

Pero antes de cambiar nada, creo que la gente debe pensar en esto ...

En esencia, el problema está relacionado con tener modelos que uno no desea utilizar para añadir más de una opción de un menú desplegable, una vez en un momento. Podría resolverse creando un conjunto de permisos para usuarios "no tan avanzados" que entran en pánico cuando hay demasiados modelos. En caso de que se requieran cambios en los modelos en particular, uno simplemente puede iniciar sesión con la "cuenta avanzada".

1

Ésta es una alternativa de construcción en la parte superior de x0nix respuesta, y sólo si usted es feliz que oculta las filas con jQuery.

Copiar pegar desde la otra respuesta la parte que reutilicé

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) 

A continuación, instalar django-jquery y luego añadir el siguiente bloque en su /admin/index.html plantilla:

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

No es necesario copiar pegue la plantilla completa, simplemente extiéndala y anule el bloque extrahead.Necesitarás django-apptemplates para que lo anterior funcione.

11

Dado que Django 1.8, ModelAdmin tiene un nuevo método llamado has_module_permission() que es responsable de mostrar un modelo en el índice de administración.

Para ocultar un modelo del índice de administración, solo cree este método en su clase ModelAdmin y devuelva False. Ejemplo:

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

Lamentablemente, 'has_module_permission' afecta a toda la aplicación y no solo a un modelo. Por lo tanto, agregar esto a un modelo en la aplicación provoca un 403 Prohibido en la lista del modelo de la aplicación (/ admin/app_label /). Ver [django/contrib/admin/sites.py] (https://github.com/django/django/blob/255fb992845e987ef36e3d721a77747a0b2df620/django/contrib/admin/sites.py#L401). – Fabian

+1

@Fabian Creo que es un error. Lo pregunté en el canal de IRC de Django, y algunas personas coinciden en que este comportamiento no es deseado. – xyres

+0

@Fabian Suponiendo que la página de índice de administración aún tenga enlaces a _/admin/_, es posible eludir esa falla mediante algo como 'return request.path! = '/ Admin /''. Lamentablemente, esos modelos se vuelven a habilitar en la lista de modelos de la aplicación. – ecp

0

que tenía un montón de administradores de modelo para registrar y ocultar, si desea una solución más seca, esto funcionó para mí (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) 

Creo que se puede transfiéralo a una clase de utilidad si desea volver a usarlo en todas las aplicaciones.

0

A partir de Django 1.8.18, has_module_permission() todavía tiene problema. Entonces, en nuestro caso usamos también el get_model_perms(). Del mismo modo, debemos ocultar el modelo solo para usuarios específicos, pero el superuser debe poder acceder a su entrada de índice.

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) 
Cuestiones relacionadas