Hasta ahora, cualquiera que haya buscando agregar comportamientos personalizados a la interfaz de administración probablemente esté un poco frustrado. "Todo lo que han dicho es cómo cambiar la interfaz visualmente", los escuchamos llorar. "¿Pero como puedo cambiar la forma en que la interfaz de administración funciona?"
La primer cosa para entender es que esto no es mágico. Esto es, nada de lo
que la interfaz hace es especial de manera alguna — ya que se trata
simplemente de un conjunto de vistas (que se encuentran en
django.contrib.admin.views
) que manipulan datos como cualquier otra vista.
Seguro, hay bastante código allí, y se debe a que tienen que lidear con todas las opciones, diferentes tipos de campos, y configuraciones que influyen en el comportamiento. No obstante, cuando te das cuenta que la interfaz de administración es sólo un juego de vistas, agregar las tuyas propias es más fácil de entender.
A modo de ejemplo, agreguemos una vista "reporte de editores" a nuestra aplicación de libros del Capítulo 6. Construiremos una vista de administración que muestre la lista de libros en función de los editores — un ejemplo bastante típico de vista de "reporte" que puedes necesitar construir.
Primero, actualicemos nuestro archivo URLconf. Necesitamos insertar esta línea:
(r'^admin/books/report/$', 'mysite.books.admin_views.report'),
antes de la línea que incluye las vistas del administrador. Un esqueleto del URLconf puede parecerse a algo así:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^admin/libreria/reporte/$', 'libreria.admin_views.reporte'),
(r'^admin/', include('django.contrib.admin.urls')),
)
¿Por qué ponemos la vista personalizada antes de incluir las del administrador? Recuerda que Django procesa los patrones de URL en orden. La inclusión de los patrones de URLs del administrador coincide con casi cualquier cosa que llega a su punto de inclusión, por lo que si invertimos el orden de esas lineas, Django encontrará una vista por omisión para ese patrón y no funcionará como queremos. En este caso particular, intentará cargar un un lista de cambios para un modelo "Reporte" en la aplicación "libros", que no existe.
Ahora escribamos nuestra vista. Para hacer honor a la simplicidad, sólo
cargaremos todos los libros dentro del contexto, y dejaremos que la plantilla
maneje el agrupamiento con la etiqueta {% regroup %}
. Crea un archivo
books/admin_views.py
, con este código:
from mysite.books.models import Book
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.contrib.admin.views.decorators import staff_member_required
def report(request):
return render_to_response(
"admin/books/report.html",
{'book_list' : Book.objects.all()},
RequestContext(request, {}),
)
report = staff_member_required(report)
Debido a que dejamos el agrupamiento a la plantilla, esta vista es bastante simple. Sin embargo, hay algunos fragmentos sutiles dignos de explicitar:
Usamos el decorador
staff_member_required
dedjango.contrib.admin.views.decorators
. Esto es similar alogin_required
discutido en el Capítulo 12, pero este decorador también verifica que el usuario esté marcado como un mientro del "staff", y tenga en consecuencia acceso a la interfaz de administración.Este decorador protege todos las vistas predefinidas del administrador, y hace que la lógica de autenticación para tus vistas coincida con la del resto de la interfaz.
- Renderizamos una plantilla que se encuentra bajo
admin/
. Aunque esto no es estrictamente requerido, se considera una buena practica para mantener todas tus plantillas de administración agrupadas en un directorioadmin/
. También pusimos la plantilla en un directorio llamadobooks
luego de nuestra aplicación — lo que es también una buena práctica. Usamos
RequestContext
como el tercer parámetro (context_instance
) pararender_to_response
. Esto asegura que la información sobre el usuario en curso está disponible para la plantilla.Mira el Capítulo 10 para saber más sobre
RequestContext
.
Finalmente, haremos una plantilla para esta vista. Extenderemos una plantilla de la administración para que lograr que nuestra vista coincida visualmente con el resto de la interfaz:
{% extends "admin/base_site.html" %}
{% block title %}List of books by publisher{% endblock %}
{% block content %}
<div id="content-main">
<h1>List of books by publisher:</h1>
{% regroup book_list|dictsort:"publisher.name" by publisher as books_by_publisher %}
{% for publisher in books_by_publisher %}
<h3>{{ publisher.grouper }}</h3>
<ul>
{% for book in publisher.list|dictsort:"title" %}
<li>{{ book }}</li>
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}
Al extender admin/base_site.html
, conseguimos el look and feel de la
interfaz de administración de Django "gratis". La Figura 17-2 muestra como
luce el resultado.
![Una vista personalizada "libros por editor"](/static/libros/imagenes/django-1-0/books_by_publisher.png)
Figura 17.2 Una vista personalizada "libros por editor"
Puedes usar esta técnica para agregar cualquier cosa que sueñes para la interfaz de administración. Recuerda que las llamadas vistas de administración personalizadas en realidad son sólo vistas comunes de Django; por lo que puedes usar todas las técnicas aprendidas en el resto de este libro para proveer una interfaz con tanta complejidad como necesites.
Cerraremos este capítulo con algunas ideas para vistas de administración personalizadas.