Coffee bytes

Blog de desarrollo web con Python y Javascript

Eduardo Zepeda

El django admin panel y su personalización

El martes, 14 de septiembre de 2021

por Eduardo Zepeda

Tiempo de lectura: 9 minutos

Una de las mejores características de django es que cuenta con el django admin panel, un panel de administración listo para usarse, con funciones básicas como crear, leer, editar y eliminar modelos, usuarios, grupos y permisos. Todo listo con solo montar tu aplicación. Pero a veces nuestras necesidades son otras ¿y si queremos modificar la apariencia o las funciones de la interfaz? Afortunadamente Django incluye muchísimas funciones para personalizar el comportamiento del admin, te explicaré algunas a continuación.

El panel de administración de django es una de las razones por las que deberías considerar usar Django.

Revisando que django admin panel esté activo

Si iniciaste tu proyecto con el comando startproject el panel de administración de django estará activado por defecto. Si entras a /admin/ aparecerá la pantalla de logueo.

En caso de que no, o de que partas de una instalación previa, primero tienes que asegurarte de que esté instalado en tu archivo de configuraciones, así como sus dependencias:

  • django.contrib.auth
  • django.contrib.contenttypes
  • django.contrib.messages
  • django.contrib.sessions

Después de todo, si no puedes autenticarte ni iniciar sesión pues no podrás entrar al panel de administración ¿no?

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    # ...
]

También debes agregar django.contrib.messages.context_processors.messages y django.contrib.auth.context_processors.auth a la opción de context_processors en la variable TEMPLATES de tu archivo settings.py

De la misma manera agrega django.contrib.auth.middleware.AuthenticationMiddleware y django.contrib.messages.middleware.MessageMiddleware a la variable MIDDLEWARE también de tu archivo settings.py.

Ahora que estamos seguros de que el paquete admin está activo, empecemos agregando un modelo. Voy a usar un modelo hipotético llamado Videogame que luce de la siguiente manera

# videogameStore/models.py
from django.db import models
GENRES = (
        ('HR', 'Horror'),
        ('AD', 'Adventure')
    )

class Videogame(models.Model):
    name = models.CharField(max_length=256)
    description = models.TextField(blank="true")
    genre = models.CharField(choices=GENRES, max_length=2)
    rating = models.FloatField()
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

Agregar un modelo al django admin panel

Empecemos con lo básico, agregar un modelo al admin.

# videogameStore/admin.py
from django.contrib import admin
from .models import Videogame

admin.site.register(Videogame)

Con esto ya tendremos un modelo modificable en el admin.

Si entramos a la dirección url /admin/ nos logueamos, podremos ver la interfaz funcionando.

Nota la ausencia de barra de búsqueda

Si le damos click en el botón gris que está en la esquina superior derecha podremos agregar un modelo.

Modificando los campos que aparecen en el admin

En el archivo admin.py dentro de nuestra aplicación de Django vamos a heredar de la clase admin.ModelAdmin.

Podemos dotar a este modelo de la propiedad list_display, para decirle al admin que campos queremos listar en el administrador.

La propiedad search_field nos permite especificar sobre que campos va a efectuarse la búsqueda.

 # videogameStore/admin.py
from django.contrib import admin
from .models import Videogame

class VideogameAdmin(admin.ModelAdmin):
      list_display = ('name', 'created') #Ahora la interfaz mostrará nombre, apellido y email de cada autor.
      search_fields = ('name', 'description')

admin.site.register(Videogame, VideogameAdmin)
Mira el campo created y la barra de búsqueda

Modificar el orden de los campos al editar

Si queremos modificar el orden de los campos agregamos una propiedad fields a nuestra clase

# videogameStore/admin.py
from django.contrib import admin
from .models import Videogame

class VideogameAdmin(admin.ModelAdmin):
      list_display = ('name', 'created') #Ahora la interfaz mostrará nombre, apellido y email de cada autor.
      search_fields = ('name', 'description')
      fields = ('description', 'name', 'genre', 'rating')
admin.site.register(Videogame, VideogameAdmin)

Como puedes apreciar, el orden en que aparecen los campos se ha modificado. En orden Description, Name, Genre y Rating, justo como lo especificamos.

Observa como el orden ha cambio al especificado en la propiedad fields

Ordenando los objetos por un campo

Ordering especifica el campo que se usará para ordenar los modelos.

# videogameStore/admin.py
from django.contrib import admin
from .models import Videogame

class VideogameAdmin(admin.ModelAdmin):
      list_display = ('name', 'created') #Ahora la interfaz mostrará nombre, apellido y email de cada autor.
      search_fields = ('name', 'description')
      fields = ('description', 'name', 'genre', 'rating')
      ordering = ('-name',)
admin.site.register(Videogame, VideogameAdmin)

Aquí le hemos dicho que los ordene por su nombre, de manera descendente, usando el símbolo «-«.

Nota el acomodo de los modelos en orden descendente

Modificando la cabecera, el título y la descripción

Si quieres darle un toque personalizado al admin de Django, incluso poniéndole el nombre de tu negocio, o el del negocio de tu cliente. Puedes hacerlo modificando las propiedades del modelo Admin de la siguiente manera:

# videogameStore/admin.py
# ...
admin.site.site_header = 'Nombre de mi sitio'
admin.site.index_title = 'Panel de control de mi sitio'
admin.site.site_title = 'Titulo en la pestaña del navegador'

Ahora puedes apreciar que en la página principal del admin ya aparecen los cambios que hemos hecho.

Los tres sitios señalados han cambiado

Ordenando los objetos de acuerdo a un campo de fecha

Si agregamos un campo date_hierarchy a nuestro modelo, seremos capaces de ordenar los campos de acuerdo a un campo de tipo DateTimeField o DateField en nuestro modelo.

# videogameStore/admin.py
from django.contrib import admin
from .models import Videogame

class VideogameAdmin(admin.ModelAdmin):
    # ...
    date_hierarchy = 'created'
admin.site.register(Videogame, VideogameAdmin)
La leyenda April2021 y April 30 aparecen tras colocar date_hierarchy

Crear campos dinámicos personalizados

También podemos crear campos especiales, que no forman parte del modelo, y que se generan de manera dinámica de acuerdo a información de los propios campos del modelo o de otro lugar. Por ejemplo un campo que clasifique un objeto de acuerdo a sus calificaciones.

Para crear un campo de estos agregamos el nombre del campo a list_display (para indicarle al admin que lo muestre) y creamos un método con el mismo nombre, este método recibe el objeto individual y debe retornar lo que queremos que se muestre en pantalla.

# videogameStore/admin.py
class VideogameAdmin(admin.ModelAdmin):
    list_display = ('name', 'created', 'popular')
    # ...

    def popular(self, obj):
        return "Popular" if obj.rating > 4.5 else "No es popular"

Crear acciones para el admin de Django

Todos los modelos tienen la acción de eliminar disponible, la cual permite seleccionar varias filas de la base de datos y borrarlas.

Además de la acción eliminar podemos crear nuestras propias acciones que modifiquen a nuestros elementos del admin en la manera en la que deseemos

Como ejemplo vamos a crear una acción que permite establecer un rating de 5.0 a nuestros objetos.

Primero, creamos una función que recibe modeladmin, request y el queryset como argumentos. El queryset contendrá todos los objetos que seleccionaremos en la interfaz. Y también podemos agregar un mensaje que se muestre cuando se ejecuta la acción.

# videogameStore/admin.py
from django.contrib import admin
from django.contrib import messages
from .models import Videogame
# Register your models here.


class VideogameAdmin(admin.ModelAdmin):
    # Ahora la interfaz mostrará nombre, apellido y email de cada autor.
    # ...

    def rate_five_stars(modeladmin, request, queryset):
        queryset.update(rating=5.0)
        messages.success(request, "Se calificó con 5 estrellas")

    admin.site.add_action(rate_five_stars, "Calificar con 5 estrellas")

Una vez creado el método, lo agregamos al admin por medio de su método add_action(), pasándole el método que creamos y el nombre que queremos que aparezca en pantalla para referirse a esa acción, como primer y segundo argumento, respectivamente.

Si seleccionamos algunos elementos y ejecutamos la acción, los calificará con 5 estrellas y nos aparecerá el mensaje que definimos.

Instalando plantillas externas para django admin

Existen bastantes paquetes que modifican la apariencia del admin, un ejemplo de estos es django-material-admin.

Vamos a instalarlo

pipenv install django-material-admin

Y ahora modificamos nuestra variable INSTALLED_APPS

# settings.py
# ...

INSTALLED_APPS = [
    'material',
    'material.admin',
    # removemos django.contrib.admin
    'django.contrib.auth',
    # ...
]

Podemos agregar un campo extra a nuestros modelos de admin para cambiar los íconos, basta con colocar el nombre que aparece en la documentación de materialize.

# videogameStore/admin.py
from django.contrib import admin
from .models import Videogame

class VideogameAdmin(admin.ModelAdmin):
    # ...
    icon_name = 'gamepad'
admin.site.register(Videogame, VideogameAdmin)

Si ahora accedemos al admin, podremos ver una nueva terminal mucho más estilizada. Y también un panel de administración más llamativo.

Panel de administración de Django con django-material
Panel de logueo del admin de django con django-material

Usé este paquete en especial porque se instala muy fácil y le da un aspecto completamente diferente al admin. Pero existen muchas otras opciones disponibles que puedes elegir, algunas de pago y otras gratuitas.

Volver el django admin más seguro

Es recomendable cambiar la url predeterminada, /admin/, a otra menos obvia, esto con la finalidad de prevenir ataques por fuerza bruta, si el atacante no conoce la dirección del django admin, le será imposible intentar adivinar tu contraseña por fuerza bruta.

También hay paquetes que crean un panel de administración falso que puedes monitorear, para conocer aquellas direcciones IP que intentan apoderarse de tu sitio por medio del panel de administración, uno de ellos es django-admin-honeypot. Una vez que identificas estas direcciones IP, puedes limitar su acceso, ponerlas en una lista negra o bloquearlas por completo.

Si necesitas funcionalidades extra para el admin, revisa la documentación oficial de Django.

Presume lo que aprendiste en redes

Únete a mi comunidad de lectores

Recibe contenido como este por correo electrónico, una vez por semana, de manera totalmente gratuita.

* Campo obligatorio