El sitio de administración de Django

Para una cierta clase de sitios Web, una interfaz de administración es una parte esencial de la infraestructura. Se trata de una interfaz basada en Web, limitada a los administradores del sitio de confianza, que permite la adición, la edición, y la eliminación de contenido del sitio.

Los paquetes django.contrib

La administración automática de Django es parte de una gran suite de funcionalidad de Django llamada django.contrib – la parte de código de Django que contiene diversas utilidades para el núcleo. Usted puede pensar en django.contrib como el equivalente de Django de la librería estándar de Python. Está integrado con Django de modo que no tenemos que reinventar la rueda en nuestras propias aplicaciones.

El sitio de administración se llama django.contrib.admin. Otras características disponibles en django.contrib incluyen un sistema de autenticación de usuarios (django.contrib.auth), soporte para sesiones anónimas (django.contrib.sessions), e incluso un sistema de comentarios de usuarios (django.contrib.comments).

Activar la interfaz de administración

El sitio de administración de Django es totalmente opcional, ya que sólo ciertos tipos de sitios necesitan esta funcionalidad. Eso significa que usted tendrá que dar unos pasos para activarlo en su proyecto.

En primer lugar, hacer unos cuantos cambios a su archivo de configuración:

  1. Añadir ‘django.contrib.admin’ a la propiedad INSTALLED_APPS.
  2. Asegúrese de que INSTALLED_APPS contiene ‘django.contrib.auth’, ‘django.contrib.contenttypes’, y ‘django.contrib.sessions’. El sitio de administración de Django requiere de estos tres paquetes.
  3. Asegúrese de que MIDDLEWARE_CLASSES contiene los valores ‘django.middleware.common.CommonMiddleware’,
    ‘django.contrib.sessions.middleware.SessionMiddleware’, y ‘django.contrib.auth.middleware.AuthenticationMiddleware.

En segundo lugar, ejecutar python manage.py syncdb. Este paso permitirá instalar las tablas extra de base de datos que utiliza el interfaz de administración. La primera vez que ejecute syncdb con ‘django.contrib.auth’ en INSTALLED_APPS, se le preguntará sobre la creación de un super-usuario. Si usted no hace esto, tendrá que para ejecutar python manage.py createsuperuser por separado para crear una cuenta de usuario administrador, de lo contrario usted no será capaz de entrar en el sitio de administración.

En tercer lugar, agregue el sitio de administración a su URLconf (en urls.py, recuerde). Por defecto, el urls.py generado por django-admin.py startproject contiene el código comentado para la administración de Django, y todo lo que tiene que hacer es quitar los comentarios.

# Include these import statements…
from django.contrib import admin
admin.autodiscover()

# And include this URLpattern…
urlpatterns = patterns(”,

# …
(r’^admin/’, include(admin.site.urls)),
# …

)

Con esa poca configuración, ahora usted puede ver el sitio de administración de Django en acción.  Simplemente ejecute el servidor de desarrollo (python manage.py runserver) y visite http://127.0.0.1:8000/admin/ en su navegador Web.

Usar el sitio de administración

Inicie sesión con el nombre de usuario y contraseña que agregó cuando creó el superusuario. Si usted no puede abrir una sesión, asegúrese de que ha creado realmente un super-usuario ejecutando python manage.py createsuperuser.

Una vez que esté conectado, lo primero que verá será la página de inicio de administración. Esta página muestra todos los tipos de datos disponibles que se pueden editar en el sitio de administración. En este punto, ya que no ha activado ninguno de nuestros modelos, la lista es escasa: sólo incluye Grupos y Usuarios, que son los dos modelos de administración por defecto editables.

Cada tipo de datos en el sitio de administración de Django tiene una lista de cambios y un formulario de edición. Las listas de cambios muestran todos los objetos disponibles en la base de datos, y los formularios de edición le permiten añadir, cambiar o eliminar registros particulares en su base de datos.

Haga clic en el vínculo Cambiar en la fila de los usuarios para cargar la página de lista de cambios de los usuarios. Esta página muestra todos los usuarios de la base de datos.

Pulse un nombre de usuario, y verá el formulario de edición de ese usuario. Esta página le permite cambiar los atributos del usuario.

Añadir modelos al sitio de administración

Vamos a añadir nuestros propios modelos a la página de administración a fin de que podemos agregar, modificar y eliminar objetos en nuestras tablas de bases de datos personalizadas utilizando esta interfaz agradable.

Vamos a seguir el ejemplo de los libros, donde definimos tres modelos: Publisher, Author, y Book.

En el directorio de libros (mysite/books), cree un archivo llamado admin.py, y escriba las siguientes líneas de código:

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book

admin.site.register(Publisher)
admin.site.register(Author)
admin.site.register(Book)

Este código le indica al sitio de administración de Django que ofrezca una interfaz para cada uno de estos modelos.

Una vez que haya hecho esto, vaya a la página de inicio de administración en su explorador Web (http://127.0.0.1:8000/admin/). Usted debe ver una sección de Libros con enlaces a los autores, libros y editores. Tendrá que reiniciar runserver para que los cambios tengan efecto.

Un aspecto digno de mencionar aquí es el manejo de las claves ajenas y las relaciones muchos-a-muchos por el sitio de administración, las cuales aparecen en el modelo Book.

En la página Add Book del sitio de administración de Django (http://127.0.0.1:8000/admin/books/book/add/), el editor (una ForeignKey) es representado por una caja de selección, y el campo de los autores (un ManyToManyField) es representado por un cuadro de selección múltiple. Ambos campos están al lado de un signo más verde que te permite añadir los registros relacionados de ese tipo. Por ejemplo, si hace clic en el signo más verde junto al campo Publisher, obtendrá una ventana emergente que le permite añadir un editor.

Cómo trabaja el sitio de administración

Cuando Django carga su URLconf de urls.py al arrancar el servidor, se ejecuta la setencia admin.autodiscover() que añadimos como parte de la activación de la administración. Esta función itera sobre la configuración de INSTALLED_APPS y busca un archivo llamado admin.py en cada aplicación instalada. Si un admin.py existe en una aplicación dada, se ejecuta el código de ese fichero.

En el admin.py de nuestra aplicación books, cada llamada a admin.site.register() simplemente registra el modelo dado con la administración. El sitio de administración mostrará una interfaz de edición/modificación para cada modelo que se haya registrado de forma explícita.

La aplicación django.contrib.auth incluye su propio admin.py, por lo que usuarios y grupos se mostraron de forma automática en la administración.

El sitio de administración de Django es sólo una aplicación Django, con sus propios modelos, plantillas, vistas, y patrones URL. Usted puede examinar sus plantillas, vistas, y patrones URL hurgando en django / contrib / admin en su copia del código base de Django.

Hacer campos opcionales

Usted notará probablemente una limitación – los formularios de edición requieren que se rellenen todos los campos, mientras que en muchos casos le gustaría que determinados campos fuesen opcionales. Digamos, por ejemplo, que queremos que nuestro campo email del modelo Author sea opcional, es decir, que se permita una cadena en blanco. En el mundo real, usted no podría tener una dirección de correo electrónico en archivo para cada autor.

Para especificar que el campo de correo electrónico es opcional, modificar el modelo Author. Basta con añadir blank = True para el campo email, así:

class Author(models.Model):

first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True)

Al añadir blank = True, hemos comenzado la expansión de nuestro modelo más allá de una simple definición de la tabla de base de datos. Ahora, nuestra clase de modelo está empezando a convertirse en una rica colección de conocimiento sobre lo que los objetos Author son y qué pueden hacer. No sólo está el campo email representado por una columna VARCHAR en la base de datos, sino que es también un campo opcional en contextos como el sitio de administración de Django.

Hacer a fechas y campos numéricos opcionales

SQL tiene su propia forma de especificar los valores en blanco, un valor especial llamado NULL. NULL puede significar “desconocido” o “inválido”, o algún otro significado específico de la aplicación. En SQL, un valor de NULL es diferente de una cadena vacía, al igual que el objeto especial de Python None es diferente de la una cadena vacía (“”).

Esto puede causar confusión y ambigüedad no deseados: ¿Por qué este disco tiene un valor NULL, pero este otro tiene una cadena vacía? ¿Hay una diferencia, o se introdujeron los datos de manera distinta?. Y ¿Cómo puedo obtener todos los registros que tienen un valor en blanco, debería buscar tanto los registros NULL como las cadenas vacías, o debo elegir sólo los que tienen cadenas vacías?

Para evitar esa ambigüedad, Django genera automáticamente sentencias CREATE TABLE añadiendo un valor explícito NOT NULL a cada definición de columna.

En la mayoría de los casos, este comportamiento predeterminado es óptimo para su aplicación y le ahorrará dolores de cabeza por inconsistencia de los datos. Y funciona muy bien con el resto de Django, tales como el sitio de administración de Django, que inserta una cadena vacía (no un valor NULL) cuando se deja un campo de carácter en blanco.

Pero hay una excepción con los tipos de columna de base de datos que no aceptan cadenas vacías como valores válidos, tales como fechas, horas y números. Si intenta insertar una cadena vacía en una columna de fecha o número entero, lo más probable es obtener un error de base la de datos. En este caso, NULL es la única manera de especificar un valor vacío. En los modelos Django, usted puede especificar que se permite NULL añadiendo null = True a un campo.

En resumen, si desea permitir valores en blanco en un campo de fecha (por ejemplo, DateField, TimeField, DateTimeField) o campo numérico (por ejemplo, IntegerField, DecimalField, FloatField), tendrá que utilizar tanto null = True como blank = True.

Cambiemos nuestro modelo Book para permitir una fecha de publicación en blanco:

class Book(models.Model):

title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField(blank=True, null=True)

Agregar null = True es más complicado que añadir blank = True, porque null = True cambia la semántica de la base de datos, es decir, cambia la sentencia CREATE TABLE para eliminar el NOT NULL del campo publication_date. Para completar este cambio, necesitaremos actualizar la base de datos.

Por varias razones, Django no trata de automatizar los cambios en los esquemas de base de datos, por lo que es su propia responsabilidad ejecutar el ALTER TABLE adecuado siempre que se realice un cambio a un modelo. Recuerde que puede utilizar python manage.py dbshell para entrar en la shell de su servidor de base de datos. He aquí cómo quitar el NOT NULL en este caso en particular:

ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;

Ahora el formulario de edición Add Book debería permitir valores de fecha de publicación vacíos.

Personalizar etiquetas de campo

En los formularios de edición del sitio de administración, la etiqueta de cada campo se genera a partir del nombre de campo del modelo. El algoritmo es simple: Django simplemente reemplaza los guiones bajos con espacios y coloca en mayúsculas el primer carácter. Así, por ejemplo, el campo publication_date del modelo Book tiene la fecha Publicación Date.

Sin embargo, los nombres de campo no siempre se prestan a etiquetas de campo agradables en administración, así que en algunos casos es posible que desee personalizar una etiqueta. Usted puede hacer esto especificando verbose_name en el campo del modelo adecuado. Por ejemplo, así es cómo podemos cambiar la etiqueta del campo Author.email a “e-mail”, con guión:

class Author(models.Model):

first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name=’e-mail’)

Por último, tenga en cuenta que puede pasar el verbose_name como un argumento de posición, para una sintaxis más compacta. Este ejemplo es equivalente al anterior:

class Author(models.Model):

first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(‘e-mail’, blank=True)

Esto no funcionará con campos ManyToManyField o ForeignKey, debido a que requieren que el primer argumento sea una clase modelo. En esos casos, especificar verbose_name explícitamente.

Personalizar clases ModelAdmin

Los cambios que hemos hecho hasta ahora – blank = True, null = True, y verbose_name- son realmente cambios de nivel de modelo, no cambios de nivel de administración. Es decir, estos cambios son, fundamentalmente, una parte del modelo y sólo para ser utilizados por el sitio de administración, no hay nada específico de administración en ellos.

Más allá de estos, el sitio de administración de Django ofrece una gran cantidad de opciones que permiten personalizar la forma en que el sitio de administración trabaja para un modelo en particular. Tales opciones residen en clases ModelAdmin, que son clases que contienen la configuración de un modelo específico en una instancia del sitio de administración específica.

Personalizar listas de cambios

Entremos en la personalización de administración, especificando los campos que se muestran en la lista de cambios para el modelo Author. De forma predeterminada, la lista de cambios muestra el resultado de __unicode__() para cada objeto.

Podemos mejorar este comportamiento predeterminado, añadiendo algunos campos más a la muestra de la lista de cambios. Sería útil, por ejemplo, ver cada e-mail del autor en esta lista, y sería bueno poder ordenarla por nombre y apellido.

Para que esto ocurra, vamos a definir una clase ModelAdmin para el modelo de Autor. Esta clase es la clave para personalizar la administración, y una de las cosas más básicas que le permite hacer es especificar la lista de campos a mostrar en las páginas de lista de cambios. Editar admin.py para realizar estos cambios:

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book

class AuthorAdmin(admin.ModelAdmin):

list_display = (‘first_name’, ‘last_name’, ‘email’)

admin.site.register(Publisher)
admin.site.register(Author, AuthorAdmin)
admin.site.register(Book)

Volver a cargar la página de lista de cambios del autor, y verá que ahora se muestran tres columnas: el nombre, el apellido y la dirección de correo electrónico. Además, cada una de esas columnas es ordenable haciendo clic en el encabezado de la columna.

Ahora agreguemos una barra de búsqueda simple. Añadir a search_fields a AuthorAdmin, así:

class AuthorAdmin(admin.ModelAdmin):

list_display = (‘first_name’, ‘last_name’, ‘email’)
search_fields = (‘first_name’, ‘last_name’)

Actualice la página en su navegador, y debería ver una barra de búsqueda en la parte superior. Hemos incluido una barra de búsqueda que busca en los campos first_name y last_name. Ahora agreguemos algunos filtros de fecha para nuestra página de lista de cambios del modelo Book:

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book

class AuthorAdmin(admin.ModelAdmin):

list_display = (‘first_name’, ‘last_name’, ‘email’)
search_fields = (‘first_name’, ‘last_name’)

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)

admin.site.register(Publisher)
admin.site.register(Author, AuthorAdmin)
admin.site.register(Book, BookAdmin)

Hemos utilizado list_filter, que fija en una tupla los campos a utilizar para crear filtros en el lado derecho de la página de lista de cambios. Para los campos fecha, Django proporciona accesos directos para filtrar la lista por “Hoy”, “Últimos 7 días”, “Este mes”, y “Este año”.

list_filter también trabaja en campos de otros tipos, no sólo DateField. (Pruebe con los campos BooleanField y ForeignKey, por ejemplo.) Los filtros se muestran siempre que haya por lo menos dos valores a elegir.

Otra manera de ofrecer filtros de fecha es utilizar la opción de administración date_hierarchy, así:

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)
date_hierarchy = ‘publication_date’

Tenga en cuenta que date_hierarchy toma una cadena, no una tupla, porque sólo un campo de fecha puede utilizarse para la jerarquía.

Por último, vamos a cambiar el orden por defecto en que se muestran los libros en la página de lista de cambios a siempre ordenado descendente por la fecha de su publicación.

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)
date_hierarchy = ‘publication_date’
ordering = (‘-publication_date’,)

Usando estas opciones, usted puede hacer una interfaz de edición de datos muy potente, lista para producción, con sólo unas pocas líneas de código.

Personalizar los formularios de edición

En primer lugar, vamos a personalizar la manera en que se ordenan los campos. De forma predeterminada, el orden de los campos en un formulario de edición corresponde al orden en que están definidas en el modelo. Nosotros podemos cambiar eso utilizando la opción fields en nuestra subclase ModelAdmin:

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)
date_hierarchy = ‘publication_date’
ordering = (‘-publication_date’,)
fields = (‘title’, ‘authors’, ‘publisher’, ‘publication_date’)

Otra cosa útil de la opción fields es que permite excluir a ciertos campos de la edición. Sólo dejando fuera los campo(s) que desea excluir. Por ejemplo, en nuestra base de datos de libros, se podría impedir que el campo publication_date fuese editable:

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)
date_hierarchy = ‘publication_date’
ordering = (‘-publication_date’,)
fields = (‘title’, ‘authors’, ‘publisher’)

Otro uso común de personalizar los formularios de edición tiene que ver con los campos muchos a muchos. El sitio de administración representa cada ManyToManyField como una caja de selección múltiple. Si desea seleccionar varios elementos, hay que mantener pulsada la tecla Control. El sitio de administración amablemente inserta un fragmento de texto que explica esto, pero, aún así, se hace difícil de manejar cuando su campo contiene cientos de opciones. La solución del sitio de administración es filter_horizontal.

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)
date_hierarchy = ‘publication_date’
ordering = (‘-publication_date’,)
filter_horizontal = (‘authors’,)

Recomendamos el uso filter_horizontal para cualquier ManyToManyField que tenga más de diez elementos. Es mucho más fácil de utilizar.También, recuerde que puede usar filter_horizontal en múltiples campos, especificando solamente cada nombre en la tupla. Las clases ModelAdmin también tienen una opción filter_vertical. Funciona exactamente como filter_horizontal, pero la interfaz coloca las dos casillas verticalmente en vez de horizontalmente. Es una cuestión de gusto personal.

filter_horizontal y filter_vertical funcionan sólo en los campos ManyToManyField, no en campos ForeignKey. Por defecto, el sitio de administración usa <select> simples para los campos ForeignKey, pero, como para ManyToManyField, a veces usted no quiere incurrir en la sobrecarga de tener que seleccionar todos los objetos relacionados con la pantalla en el menú desplegable. Por ejemplo, si nuestra base de datos de libros crece para incluir a miles de editores, el formulario Add Book podría tardar bastante en cargar, ya que tiene que cargar cada editor a mostrar en el cuadro <select>.

Puedes solucionar este problema con una opción llamada raw_id_fields. Ponga esto en una tupla de nombres de campo ForeignKey, y los campos se mostrarán en el administrador con una caja de entrada de texto simple (<input type = “text”>) en lugar de un <select>.

class BookAdmin(admin.ModelAdmin):

list_display = (‘title’, ‘publisher’, ‘publication_date’)
list_filter = (‘publication_date’,)
date_hierarchy = ‘publication_date’
ordering = (‘-publication_date’,)
filter_horizontal = (‘authors’,)
raw_id_fields = (‘publisher’,)

¿Qué introduciría en este cuadro de entrada? El identificador de la base de datos del editor.Teniendo en cuenta que los seres humanos normalmente no memorizan identificadores base de datos, hay un icono en el que puede hacer clic para iniciar una ventana desde la que puede seleccionar el editor.

Usuarios, grupos y permisos

Ya que está conectado como super-usuario, tiene acceso a crear, editar y eliminar cualquier objeto. Naturalmente, los diferentes entornos requieren de sistemas de autorización diferentes, no todos pueden o deben ser un superusuario. El sitio de administración de Django utiliza un sistema de permisos que se puede utilizar para dar acceso específico a los usuarios a las partes de la interfaz que necesitan.

Estas cuentas de usuario están destinadas a ser lo suficientemente generales como para utilizarse fuera de la interfaz de administración, pero las trataremos como cuentas de usuario de administración por ahora.

Puede editar los usuarios y los permisos a través de la interfaz de administración al igual que cualquier otro objeto. Los objetos de usuario tiene los campos nombre de usuario estándar, contraseña, e-mail, y nombre real, junto con un conjunto de campos que definen lo que el usuario puede hacer en la interfaz de administración. En primer lugar, hay un conjunto de 3 banderas boolean:

  • El flag “activo” controla si el usuario está activo.
  • El flag “staff” controla si el usuario tiene permiso para acceder a la interfaz de administración.
  • El flag “superusuario” proporciona al usuario acceso completo a agregar, crear y eliminar cualquier elemento de la interfaz de administración.

Los usuarios de administración “normales” – es decir, los miembros activos, no superusuarios – se les concede acceso de administración a través de los permisos asignados. Cada objeto editable a través de la interfaz de administración (por ejemplo, libros, autores, editores) tiene tres permisos: crear, editar y eliminar. La asignación de permisos a un usuario concede al usuario el correspondiente nivel de acceso.

Al crear un usuario, dicho usuario no tiene permisos. Por ejemplo, usted puede dar a un usuario permiso para agregar y cambiar los editores, pero no para eliminarlos. Tenga en cuenta que estos permisos se definen por el modelo, no por objeto, de forma que usted diga, “Juan puede hacer cambios en cualquier libro,” pero no le permite decir, “Juan puede hacer los cambios de cualquier libro publicado por Apress. ”

También puede asignar usuarios a grupos. Un grupo es simplemente un conjunto de permisos que se aplican a todos los miembros de ese grupo. Los grupos son útiles para la concesión de permisos idénticos a un subconjunto de usuarios.

Enlaces Relacionados: