¿Cómo anular y extender las plantillas básicas de administración de Django?

¿Cómo sobrescribo una plantilla de administración (por ejemplo, admin / index.html) mientras la extiendo al mismo tiempo (vea https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing) -an-admin-plantilla )?

Primero: sé que esta pregunta se ha formulado y respondido antes (vea Django: Anulación Y extensión de una plantilla de aplicación ) pero como la respuesta dice que no es directamente aplicable si está usando el cargador de plantillas de app_directories (que es la mayoría de los hora).

Mi solución actual es hacer copias y extenderlas en lugar de extenderlas directamente desde las plantillas de administración. Esto funciona muy bien, pero es realmente confuso y agrega trabajo extra cuando cambian las plantillas de administración.

Podría pensar en alguna etiqueta extensible personalizada para las plantillas, pero no quiero reinventar la rueda si ya existe una solución.

En una nota: ¿Alguien sabe si este problema será resuelto por Django?

Actualización :

Lea los documentos para su versión de Django. p.ej

https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#admin-overriding-templates https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#admin-overriding -plantillas

Respuesta original de 2011:

Tuve el mismo problema hace aproximadamente un año y medio y encontré un buen cargador de plantillas en djangosnippets.org que lo hace fácil. Le permite extender una plantilla en una aplicación específica, lo que le brinda la posibilidad de crear su propio admin / index.html que extiende la plantilla admin / index.html desde la aplicación admin. Me gusta esto:

{% extends "admin:admin/index.html" %} {% block sidebar %} {{block.super}} 

Extra links

My extra link
{% endblock %}

He dado un ejemplo completo sobre cómo usar este cargador de plantillas en una publicación de blog en mi sitio web.

En cuanto a que Django 1.8 es la versión actual, no es necesario establecer un enlace simbólico, copiar los admin / templates en la carpeta de su proyecto o instalar middlewares como lo sugieren las respuestas anteriores. Esto es lo que hay que hacer:

  1. crear la siguiente estructura de árbol (recomendado por la documentación oficial )

     your_project |-- your_project/ |-- myapp/ |-- templates/ |-- admin/ |-- myapp/ |-- change_form.html <- do not misspell this 

Nota : la ubicación de este archivo no es importante. Puedes ponerlo dentro de tu aplicación y aún funcionará. Siempre y cuando su ubicación pueda ser descubierta por django. Lo que es más importante es que el nombre del archivo HTML debe ser el mismo que el nombre del archivo HTML original proporcionado por django.

  1. Agrega esta ruta de plantilla a tu configuración.py :

     TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # <- add this line 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] 
  2. Identifique el nombre y el bloque que desea anular. Esto se hace buscando en el directorio admin / templates de django. Estoy usando virtualenv, así que para mí, la ruta está aquí:

     ~/.virtualenvs/edge/lib/python2.7/site-packages/django/contrib/admin/templates/admin 

En este ejemplo, quiero modificar el formulario para agregar nuevo usuario. La plantilla responsable de esta vista es change_form.html . Abra el archivo change_form.html y encuentre el {% block%} que desea extender.

  1. En tu change_form.html , escribe cosas como esta:

     {% extends "admin/change_form.html" %} {% block field_sets %} {# your modification here #} {% endblock %} 
  2. Carga tu página y deberías ver los cambios.

Si necesita sobrescribir el admin/index.html , puede establecer el parámetro index_template del AdminSite .

p.ej

 # urls.py ... from django.contrib import admin admin.site.index_template = 'admin/my_custom_index.html' admin.autodiscover() 

y coloque su plantilla en /templates/admin/my_custom_index.html

Con django 1.5 (al menos) puede definir la plantilla que desea usar para un modo determinado de modeladmin

vea https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#custom-template-options

Puedes hacer algo como

 class Myadmin(admin.ModelAdmin): change_form_template = 'change_form.htm' 

Con change_form.html es una plantilla html simple que se extiende admin/change_form.html (o no, si quieres hacerlo desde cero)

La respuesta de Chengs es correcta, sin embargo, de acuerdo con los documentos de administración, no todas las plantillas de administración pueden sobrescribirse de esta manera: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#overriding-admin-templates

Plantillas que pueden ser anuladas por aplicación o modelo

No todas las plantillas en contrib / admin / templates / admin pueden ser anuladas por aplicación o por modelo. Los siguientes pueden:

 app_index.html change_form.html change_list.html delete_confirmation.html object_history.html 

Para aquellas plantillas que no pueden ser anuladas de esta manera, aún puede anularlas para todo su proyecto. Simplemente coloque la nueva versión en su directorio templates / admin . Esto es particularmente útil para crear páginas 404 y 500 personalizadas.

Tuve que sobrescribir el login.html del administrador y, por lo tanto, tuve que colocar la plantilla sobrescrita en esta estructura de carpetas:

 your_project |-- your_project/ |-- myapp/ |-- templates/ |-- admin/ |-- login.html <- do not misspell this 

(sin la subcarpeta myapp en el administrador) No tengo suficiente reputación como para comentar sobre la publicación de Cheng, por eso tuve que escribir esto como una nueva respuesta.

La mejor manera de hacerlo es colocar las plantillas de administración de Django dentro de su proyecto. Así que sus plantillas estarán en templates/admin mientras que las plantillas de administración de Django estarán en say template/django_admin . Entonces, puedes hacer algo como lo siguiente:

templates / admin / change_form.html

 {% extends 'django_admin/change_form.html' %} Your stuff here 

Si le preocupa mantener las plantillas de inventario actualizadas, puede incluirlas con svn externals o similar.

Estoy de acuerdo con Chris Pratt. Pero creo que es mejor crear el enlace simbólico a la carpeta Django original donde se ubican las plantillas de administración en:

 ln -s /usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/admin/ templates/django_admin 

y como puedes ver, depende de la versión de python y de la carpeta donde se instaló Django. Por lo tanto, en el futuro o en un servidor de producción, es posible que deba cambiar la ruta.

No pude encontrar una sola respuesta o una sección en los documentos oficiales de Django que tuvieran toda la información que necesitaba para anular / ampliar las plantillas de administración predeterminadas, por lo que escribo esta respuesta como una guía completa, con la esperanza de que sea útil. para otros en el futuro.

Asumiendo la estructura estándar del proyecto Django:

 mysite-container/ # project container directory manage.py mysite/ # project package __init__.py admin.py apps.py settings.py urls.py wsgi.py app1/ app2/ ... static/ templates/ 

Esto es lo que necesitas hacer:

  1. En mysite/admin.py , cree una subclase de AdminSite :

     from django.contrib.admin import AdminSite class CustomAdminSite(AdminSite): # set values for `site_header`, `site_title`, `index_title` etc. site_header = 'Custom Admin Site' ... # extend / override admin views, such as `index()` def index(self, request, extra_context=None): extra_context = extra_context or {} # do whatever you want to do and save the values in `extra_context` extra_context['world'] = 'Earth' return super(CustomAdminSite, self).index(request, extra_context) custom_admin_site = CustomAdminSite() 

    Asegúrese de importar custom_admin_site en admin.py de sus aplicaciones y registre sus modelos en ellas para mostrarlas en su sitio de administración personalizado (si lo desea).

  2. En mysite/apps.py , cree una subclase de AdminConfig y configure default_site a admin.CustomAdminSite del paso anterior:

     from django.contrib.admin.apps import AdminConfig class CustomAdminConfig(AdminConfig): default_site = 'admin.CustomAdminSite' 
  3. En mysite/settings.py , reemplace django.admin.site en INSTALLED_APPS con apps.CustomAdminConfig (la configuración de la aplicación de administración personalizada del paso anterior).

     from django.contrib.admin.apps import AdminConfig class CustomAdminConfig(AdminConfig): default_site = 'admin.CustomAdminSite' 
  4. En mysite/urls.py , reemplace admin.site.urls de la URL de administración a custom_admin_site.urls

     from .admin import custom_admin_site urlpatterns = [ ... path('admin/', custom_admin_site.urls), # for Django 1.x versions: url(r'^admin/', include(custom_admin_site.urls)), ... ] 
  5. Cree la plantilla que desea modificar en su directorio de templates , manteniendo la estructura de directorios predeterminada de las plantillas de administración de Django como se especifica en los documentos . Por ejemplo, si estaba modificando admin/index.html , cree las templates/admin/index.html archivo templates/admin/index.html .

    Todas las plantillas existentes se pueden modificar de esta manera, y sus nombres y estructuras se pueden encontrar en el código fuente de Django .

  6. Ahora puede anular la plantilla escribiéndola desde cero o extendiéndola y luego anular / extender bloques específicos.

    Por ejemplo, si desea mantener todo como está pero desea anular el bloque de content (que en la página de índice enumera las aplicaciones y sus modelos que registró), agregue lo siguiente a templates/admin/index.html :

     {% extends 'admin/index.html' %} {% block content %} 

    Hello, {{ world }}!

    {% endblock %}

    Para preservar el contenido original de un bloque, agregue {{ block.super }} donde desee que se muestre el contenido original:

     {% extends 'admin/index.html' %} {% block content %} 

    Hello, {{ world }}!

    {{ block.super }} {% endblock %}

    También puede agregar estilos y scripts personalizados modificando los bloques extrastyle y extrastyle .

Este sitio tenía una solución simple que funcionaba con mi configuración Django 1.7.

PRIMERO: Cree un enlace simbólico denominado admin_src en el directorio / plantilla de su proyecto a sus plantillas Django instaladas. Para mí en Dreamhost usando un virtualenv, mis “fonts” de plantillas de administrador de Django estaban en:

 ~/virtualenvs/mydomain/lib/python2.7/site-packages/django/contrib/admin/templates/admin 

SEGUNDO: Crea un directorio de administración en plantillas /

Así que la plantilla / directorio de mi proyecto ahora se veía así:

 /templates/ admin admin_src -> [to django source] base.html index.html sitemap.xml etc... 

TERCERO: en su nueva plantilla / admin / directorio cree un archivo base.html con este contenido:

 {% extends "admin_src/base.html" %} {% block extrahead %}  {% endblock %} 

CUARTO: Añada su admin favicon-admin.ico a su carpeta img de raíz estática.

Hecho. Fácil.

Puede usar django-overextends , que proporciona una herencia de plantilla circular para Django.

Viene del CMS Mezzanine , desde donde Stephen lo extrajo en una extensión Django independiente.

Más información se encuentra en “Anulación frente a la ampliación de plantillas” (http: /mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates) dentro de los documentos Mezzanine.

Para obtener información más detallada, consulte el blog de Stephens “Herencia de la plantilla circular para Django” (http: /blog.jupo.org/2012/05/05/17/circular-template-inheritance-for-django).

Y en la discusión de Grupos de Google (https: /groups.google.com/forum / #! Topic / mezzanine-users / sUydcf_IZkQ) que inició el desarrollo de esta función.

Nota:

No tengo la reputación de agregar más de 2 enlaces. Pero creo que los enlaces proporcionan información de fondo interesante. Así que simplemente dejé una barra después de “http (s):”. Tal vez alguien con mejor reputación pueda reparar los enlaces y eliminar esta nota.

para el índice de la aplicación, agregue esta línea a algún archivo py común como url.py

 admin.site.index_template = 'admin/custom_index.html' 

para el índice del módulo de la aplicación: agregue esta línea a admin.py

 admin.AdminSite.app_index_template = "servers/servers-home.html" 

para la lista de cambios: agregue esta línea a la clase de administración:

 change_list_template = "servers/servers_changelist.html" 

para la plantilla de formulario del módulo de aplicación: agregue esta línea a su clase de administrador

 change_form_template = "servers/server_changeform.html" 

etc. y encontrar otros en las mismas clases de módulos de administrador.