Escribiendo tu primera Django app, parte 6

Este tutorial empieza donde dejó el Tutorial 5. Hemos construido una aplicación web de preguntas, y ahora vamos a agregar una hoja de estilos y una imagen.

Además del HTML generado por el servidor, las aplicaciones web en general necesitan servir archivos adicionales — como imágenes, JavaScript o CSS — necesarios para renderizar la página web completa. En Django nos referimos a estos archivos como “static files” (archivos estáticos).

Para proyectos pequeños esto no es un gran problema, porque uno mantiene los archivos estáticos en algún lugar que el servidor web los pueda encontrar. Sin embargo, en proyectos grandes – especialmente aquellos compuestos por múltiples apps – manejar múltiples conjuntos de archivos estáticos provistos por cada aplicación empieza a volverse complejo.

Para esto está django.contrib.staticfiles: reúne los archivos estáticos de cada una de nuestras aplicaciones (y cualquier otro lugar que uno especifique) en una única ubicación que pueda ser fácilmente servida en producción.

Personalizando el look and feel de nuestra app

Primero, creamos un directorio llamado static en nuestro directorio polls. Django va a buscar archivos estáticos allí, de forma similar a como Django busca por templates dentro de polls/templates/.

El setting de Django STATICFILES_FINDERS contiene una lista de los “finders” (buscadores) que saben cómo encontrar los archivos estáticos en distintas fuentes. Uno de los habilitados por defecto es AppDirectoriesFinder que busca un subdirectorio static en cada una de las INSTALLED_APPS, como la app polls que hemos creado. El sitio de admin usa la misma estructura de directorios para sus archivos estáticos.

Dentro del directorio static que hemos creado, creamos otro directorio llamado polls y dentro del mismo, un archivo llamado style.css. En otras palabras, nuestra hoja de estilos estaría en polls/static/polls/style.css. Por como funciona AppDirectoriesFinder, nos podemos referir a este archivo estático en Django simplemente como polls/style.css, de forma similar a como referenciábamos templates.

Espacio de nombres de archivos estáticos

Como con los templates, podríamos poner todos nuestros archivos estáticos directamente en polls/static``(en lugar de crear un subdirectorio ``polls), pero esto no sería una buena idea. Django va a elegir el primer archivo estático que encuentre cuyo nombre coincida, y si tuviéramos un archivo del mismo nombre en otra aplicación diferente, Django no podría distinguir entre ellos. Necesitamos apuntar a Django al correcto, y la forma más fácil de asegurarse de esto es usando espacios de nombres. Esto es, poner los archivos estáticos en otro directorio que se llame como la aplicación a la que pertenecen.

Pongamos el siguiente código en la hoja de estilos (polls/static/polls/style.css):

polls/static/polls/style.css
li a {
    color: green;
}

Luego, agreguemos lo siguiente al comienzo de polls/templates/polls/index.html:

polls/templates/polls/index.html
{% load staticfiles %}

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />

{% load staticfiles %}` carga el template tag {% static %} de la librería staticfiles. El template tag {% static %} genera las URL absolutas del archivo estático.

Eso es todo lo que necesitamos para desarrollar. Recargamos http://localhost:8000/polls/ y deberíamos ver que los links a las preguntas son verdes (Django syle!), lo que significa que la hoja de estilos se cargó correctamente.

Agregando una imagen de fondo

A continuación vamos a crear un subdirectorio para imágenes. Creamos el subdirectorio images en el directorio polls/static/polls/. Dentro de ese directorio ponemos una imagen llamada background.gif. En otras palabras, ponemos nuestra imagen en polls/static/polls/images/background.gif.

Luego agreguemos a nuestra hoja de estilos (polls/static/polls/style.css):

polls/static/polls/style.css
body {
    background: white url("images/background.gif") no-repeat right bottom;
}

Recargamos http://localhost:8000/polls/ y deberíamos ver la imagen de fondo cargada en la esquina inferior derecha de la pantalla.

Advertencia

Por supuesto que el template tag {% static %} no está disponible para usar en los archivos estáticos ya que las hojas de estilo no son generadas por Django. Siempre deberías usar paths relativos para referenciar tus archivos estáticos entre sí, porque de esa forma uno puede cambiar el setting STATIC_URL (usado por el template tag static para generar las URLs), sin tener que modificar también una gran cantidad de paths en nuestros archivos estáticos.

Estos son los conceptos básicos. Para más detalles sobre los settings y otros bits incluidos en el framework, ver el howto de static files y la referencia de staticfiles. Deploying static files discute cómo usar archivos estáticos en un servidor real.

Qué sigue?

El tutorial para principiantes termina acá. A continuación podrías querer chequar algunos punteros sobre cómo seguir desde aquí.

Si estás familiarizado con empaquetar Python y estás interesado en aprender cómo convertir polls en una “app reusable”, chequeá Tutoral avanzado: Cómo escribir apps reusables.