En la página raíz del sitio de administración donde aparecen los modelos registrados, quiero ocultar varios modelos que están registrados para el administrador de Django.
Si los anulo directamente, no puedo agregar nuevos registros ya que el símbolo de agregar nuevo "+" desaparece.
¿Cómo se puede hacer esto?
django
django-admin
Hellnar
fuente
fuente
get_model_perms = lambda self, req: {}
Para Django 1.8 y superior
Desde Django 1.8,
ModelAdmin
tiene un nuevo método llamadohas_module_permission()
que es responsable de mostrar un modelo en el índice de administración.Para ocultar un modelo del índice de administración, simplemente cree este método en su
ModelAdmin
clase y regreseFalse
. Ejemplo:class MyModelAdmin(admin.ModelAdmin): ... def has_module_permission(self, request): return False
fuente
has_module_permission
afecta a toda la aplicación y no solo a un modelo. Entonces, agregar esto a un modelo en la aplicación provoca un 403 Prohibido en la lista de modelos de la aplicación (/ admin / app_label /). Consulte django / contrib / admin / sites.py .return request.path!='/admin/'
. Desafortunadamente, eso vuelve a habilitar esos modelos en la lista de modelos de la aplicación.Tengo el mismo problema, aquí lo que se me ocurrió.
Como en la solución anterior, copie index.html de django a su /admin/index.html y modifíquelo así:
{% for model in app.models %} {% if not model.perms.list_hide %} <tr> ... </tr> {% endif %} {% endfor %}
Y crea la subclase 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
Ahora, cualquier modelo registrado con la subclase HiddenModelAdmin no aparecerá en la lista de administración, pero estará disponible a través del símbolo "más" en detalle:
class MyModelAdmin(HiddenModelAdmin): ... admin.site.register(MyModel, MyModelAdmin)
fuente
Solución fea: anule la plantilla de índice de administración, es decir, copie index.html de django a su /admin/index.html y agregue algo como esto:
{% for for model in app.models %} {% ifnotequal model.name "NameOfModelToHide" %} ...
fuente
Esta es una construcción alternativa en la respuesta de x0nix superior, y solo si está contento de ocultar las filas con jquery.
Copiar pegando de 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)
Entonces instala django-jquery y luego agregue 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 y pegar toda la plantilla, solo extiéndala y anule el
extrahead
bloque. Necesitará django-apptemplates para que funcione lo anterior.fuente
Django 1.2 tiene nuevas declaraciones if, lo que significa que la función deseada solo se puede obtener sobrescribiendo admin / index.html
{% if model.name not in "Name of hidden model; Name of other hidden model" %} ... {% endif %}
Esta es una mala solución, porque no le importan los administradores en varios 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 centrales de Django.
Pero antes de cambiar nada, creo que la gente debería pensar en esto ...
Básicamente, el problema está relacionado con tener modelos que uno no desea usar para más que agregar una opción a un menú desplegable de vez en cuando. Se podría solucionar eficazmente 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 particulares, uno puede simplemente iniciar sesión con la "cuenta avanzada".
fuente
Tenía muchos administradores de modelos para registrar y ocultar, si desea una solución más DRY, 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)
Supongo que podría convertirlo en una clase de utilidad si desea reutilizarlo en todas las aplicaciones.
fuente
A partir de Django 1.8.18 ,
has_module_permission()
todavía tiene problemas. Entonces, en nuestro caso usamos también elget_model_perms()
. Del mismo modo, necesitamos ocultar el modelo solo para un usuario específico, perosuperuser
debería 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)
fuente