Escribiendo su primera aplicación Django, parte 7

Este tutorial comienza donde quedó el Tutorial 6. Continúamos con la aplicación Web encuestas y nos vamos a enfocar en personalizar el sitio administrativo de Django generado automáticamente que estudiamos primero en el Tutorial 2.

Dónde obtener ayuda:

If you’re having trouble going through this tutorial, please head over to the Getting Help section of the FAQ.

Personalice el formulario del sitio administrativo

Al registrar el modelo Question con admin.site.register (Question)`, Django pudo construir una representación del formulario predeterminado. A menudo, usted querrá personalizar el aspecto y el funcionamiento del formulario del sitio administrativo. Usted hará esto indicándole a Django las opciones que desee cuando registre el objeto.

Veamos cómo funciona esto reordenando los campos en el formulario de edición. Reemplace la línea admin.site.register(Question) con:

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

Usted seguirá este patrón - cree una clase de modelo del sitio administrativo y luego pásela como el segundo argumento a admin.site.register() - cada vez que necesite cambiar las opciones del sitio administrativo para un modelo.

Esta modificación concreta citada anteriormente hace que la «Publication date» se anteponga al campo «Question»:

Fields have been reordered

Esto no es tan impresionante con sólo dos campos, pero para los formularios del sitio administrativo con docenas de campos, elegir un orden intuitivo es un detalle importante de usabilidad.

Y hablando de formularios con docenas de campos, es posible que desee dividir el formulario en grupos de campos:

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

El primer elemento de cada tupla en fieldsets es el título del grupo de campos. Así es como se ve el formulario ahora:

Form has fieldsets now

Personalice la lista de cambios del sitio administrativo

Ahora que la página de administración Question se ve bien, vamos a hacer algunos ajustes a la página «change list» – la que muestra todas las preguntas en el sistema.

Así es como se ve en este momento:

Polls change list page

Por defecto, Django muestra el str() de cada objeto, pero a veces sería más útil si pudiéramos mostrar los campos individuales. Para hacerlo, utilice la opción del sitio administrativo :attr::~django.contrib.admin.ModelAdmin.list_display, que es una tupla de nombres de campos para que se muestre como columnas en la página de lista de cambios para el objeto:

polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date')

For good measure, let’s also include the was_published_recently() method from Tutorial 2:

polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

Ahora la página de lista de cambios de preguntas se ve así:

Polls change list page, updated

Usted puede hacer clic en las cabeceras de las columnas para ordenar por esos valores ,excepto en el caso de la cabecera was_published_recently, porque ordenar por la salida de un método arbitrario no está soportado. También tenga en cuenta que la cabecera de la columna was_published_recently es, por defecto, el nombre del método (con guiones bajos reemplazado con espacios), y que cada línea contiene la representación de cadena de la salida.

Usted puede mejorar eso al darle a ese método (en el archivo polls/models.py) algunos atributos, de la siguiente manera:

polls/models.py
class Question(models.Model):
    # ...
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

Para obtener más información sobre estas propiedades del método, consulte list_display.

Edite de nuevo su archivo polls/admin.py y añada una mejora a la página Question en la lista de cambios: filtre utilizando el list_filter. Agregue la siguiente línea a QuestionAdmin:

list_filter = ['pub_date']

Eso añade una barra lateral «Filter» que le permite a los usuarios filtrar la lista de cambios mediante el campo pub_date:

Polls change list page, updated

El tipo de filtro que se muestra depende del tipo de campo que está filtrando. Debido a que la pub_date es una DateTimeField, Django sabe dar opciones de filtro apropiadas: «Any date», «Today», «Past 7 days», «This month», «This year».

Esto se perfila bien. Vamos a añadir un poco de capacidad de búsqueda:

search_fields = ['question_text']

Eso añade un cuadro de búsqueda en la parte superior de la lista de cambios. Cuando alguien introduce los términos de búsqueda, Django buscará el campo question_text. Usted puede utilizar tantos campos como desee, sin embargo, ya que utiliza una petición LIKE detrás de bastidores, limitar el número de campos de búsqueda a un número razonable le facilitará la búsqueda a su base de datos.

Ahora también es un buen momento para señalar que las listas de cambios le dan paginación libre. El modo predeterminado muestra 100 items por página. Paginación de la lista de cambios, cuadros de búsqueda, :attr:`filtros, jerarquías de fecha y orden de la cabecera de columnas todos trabajan juntos como usted piensa que deberían.

Personalice el aspecto del sitio administrativo

Está claro que tener «Django administration» en la parte superior de cada página del sitio administrativo es ridículo. Es sólo texto del marcador de posición.

You can change it, though, using Django’s template system. The Django admin is powered by Django itself, and its interfaces use Django’s own template system.

Personalizando las plantillas de su proyecto

Cree un directorio templates en el directorio de su proyecto (el que contiene manage.py). Las plantillas se pueden ubicar en cualquier parte de su sistema de archivos al que Django pueda acceder. (Django ejecuta como cualquier usuario ejecuta su servidor.) Sin embargo, una buena práctica a seguir es guardar sus plantillas en el proyecto.

Abra el archivo de configuraciones (mysite/settings.py, recuerde) y añada una opción DIRS en la opción TEMPLATES:

mysite/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        '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',
            ],
        },
    },
]

DIRS es una lista de directorios del sistema de archivos utilizada para comprobar cuando se cargan las plantillas de Django; es una ruta de búsqueda.

Organizando las plantillas

Al igual que los archivos estáticos podríamos tener todas nuestras plantillas juntas en un gran directorio de plantillas y funcionaría perfectamente. Sin embargo, las plantillas que pertenecen a una determinada aplicación deberían ser puestas en el directorio de plantillas de la aplicación (por ejemplo, polls/templates) en lugar del directorio (templates) del proyecto. Hablaremos con más detalle por qué hacemos esto en el tutorial de aplicaciones reutilizables.

Ahora cree un directorio llamado admin dentro de templates y copie la plantilla admin/base_site.html desde dentro del directorio de plantillas predeterminado del sitio administrativo de Django en el código fuente de Django (django/contrib/admin/templates) en ese directorio.

¿Dónde están los archivos fuente de Django?

Si tiene dificultad para encontrar donde están localizados los archivos fuente de Django en su sistema, ejecute el siguiente comando:

$ python -c "import django; print(django.__path__)"
...\> py -c "import django; print(django.__path__)"

Then, edit the file and replace {{ site_header|default:_('Django administration') }} (including the curly braces) with your own site’s name as you see fit. You should end up with a section of code like:

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

Utilizamos este método para enseñarle cómo reemplazar las plantillas. En un proyecto real, usted probablemente utilizaría el atributo django.contrib.admin.AdminSite.site_header para hacer este ajuste particular con mayor facilidad.

Este archivo de plantillas contiene una gran cantidad de texto como {% block branding%} y {{title}}. Las etiquetas {% y {{ son parte del lenguaje de plantillas de Django. Cuando Django crea admin/base_site.html, este lenguaje de plantilla será evaluado para generar la página HTML definitiva, como vimos en el Tutorial 3.

Note that any of Django’s default admin templates can be overridden. To override a template, do the same thing you did with base_site.html – copy it from the default directory into your custom directory, and make changes.

Personalizando las plantillas de su aplicación

Los lectores agudos preguntarán: ¿Pero si DIRS estaba vacío por defecto, ¿Cómo Django estaba buscando las plantillas del sitio administrativo predeterminado? La respuesta es que, ya que APP_DIRS <TEMPLATES-APP_DIRS está fijado como True, Django busca automáticamente un subdirectorio templates/ dentro de cada paquete de la aplicación, para su uso como una solución alternativa (no olvide que django.contrib.admin es una aplicación).

Nuestra aplicación encuestas no es muy compleja y no necesita las plantillas personalizadas del sitio administrativo. Pero si se hiciera más sofisticada y requiriera la modificación de las plantillas convencionales del sitio administrativo de Django para algunas de sus funciones, sería más sensato modificar las plantillas de la aplicación, en lugar de las que están en el proyecto. De esa manera, usted podría incluir la aplicación encuestas en cualquier nuevo proyecto y estaría seguro de que esta encontraría las plantillas personalizadas que necesitaba.

Consulte la documentación sobre la carga de plantillas para obtener más información sobre cómo Django encuentra sus plantillas.

Personalice la página del índice del sitio administrativo

En este sentido, es posible que desee personalizar la apariencia de la página de índice del sitio administrativo de Django.

Por defecto, muestra todas las aplicaciones que se encuentran en INSTALLED_APPS que han sido registradas en la aplicación del sitio administrativo en orden alfabético. Es posible que desee realizar cambios significativos en el diseño. Después de todo, el índice es probablemente la página más importante del sitio administrativo y debería ser fácil de usar.

La plantilla a personalizar es admin/index.html. (Haga lo mismo que hizo con admin/base_site.html en la sección anterior: cópiela desde el directorio predeterminado en el directorio de plantillas personalizadas). Edite el archivo y verá que utiliza una variable de plantilla llamada app_list. Esa variable contiene todas las aplicaciones instaladas de Django. En lugar de utilizar esa, usted puede predeterminar enlaces a páginas del sitio administrativo específicas de objeto de la manera que le parezca mejor.

¿Qué sigue?

El tutorial para principiantes finaliza aquí. Mientras tanto, es posible que desee ver algunos consejos sobre a dónde ir a partir de ahora.

Si está familiarizado con el empaquetado Python e interesado en aprender cómo convertir la aplicación encuestas en una «aplicación reutilizable», consulte el tutorial avanzado: Cómo escribir aplicaciones reutilizables.

Back to Top