En el tutorial Django lo hizo un mago expliqué los conceptos básicos de
Django]. En Django lo hizo un mago: paginación y detalle añadimos paginación y
la ventana de detalle. En esta ocasión vamos a ponerlo bonito mediante
plantillas, y crearemos cierto estilo añadiendo también contextos.
Para los que sepan algo de Django, no es necesario seguir los tutoriales
anteriores, aunque sí es recomendable para los más novatos :D
Cómo leer este artículo
Nuevamente, hay tres maneras de leer este artículo.
Vamos a ahondar en el uso de plantillas, también conocidas como templates. Ya hemos visto lo básico: Las variables se rodean con doble llave {{ variable }} y los tags con llave porcentaje: {% tag [arguments] %}. Algunos tags tienen que cerrarse con {% endTAG %}. Finalmente, hay filtros (en inglés filters) que permiten modificar variables.
Los tags más importantes son if/else/endif y for/endfor. El primero nos permite añadir condiciones y el segundo, bucles. Tenéis ejemplos de ambos en el archivo templates/blog/post_list.html.
Pero no me voy a centrar en los tags o filters: Veamos la herencia.
Una plantilla puede heredar de otra. De esta manera, la plantilla padre define una estructura y la hija sobreescribe bloques. Es importante que definamos bien los bloques para que quede una buena estructura.
Veamos un ejemplo que hace uso de Bootstra] usando el CDN (archivo templates/base.html):
Básicamente, indicamos que la plantilla extiende de base.html y metemos lo que ya teníamos en el bloque content. Esto reemplazará al bloque content de la plantilla base.html.
Y con estas pequeñas modificaciones, veremos el cambio producido en la visualización de la página. Vamos a darle un poco más de estilo (templates/blog/post_list.html de nuevo):
Esto ya va pareciendo un blog en condiciones :D Si queréis podéis darle un estilo mejor, añadir una barra de navegación, etc. De la sidebar nos ocuparemos a continuación.
Context Processors
Según la documentación:
Un context processor tiene una interfaz muy simple: Es tan sólo una función que toma un argumento, un objecto HttpRequest, y devuelve un diccionario que se añade al contexto de plantillas. Cada context processor debe devolver un diccionario.
Pero… ¿Qué es el contexto? El contexto es el ámbito donde se resuelven las variables. El contexto sea el conjunto de variables que podemos usar desde las plantillas sin definirlas en la misma.
Dicho de otro modo: Los context processors nos permiten definir variables que después podremos usar desde cualquier plantilla.
Y cómo no, vamos a verlo con un ejemplo.
Vamos a crear el archivo blog/context_processors.py con el siguiente contenido:
Añadimos nuestro nuevo context_processor a la lista de context processors a cargar en el archivo app/settings.py (como estamos usando el módulo auth, hay que cargar sus context processors también):
"""
Django settings for app project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""# Build paths inside the project like this: os.path.join(BASE_DIR, ...)importosBASE_DIR=os.path.dirname(os.path.dirname(__file__))# Quick-start development settings - unsuitable for production# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!SECRET_KEY='*8l=t4nnb4ns)7d$ckxejxi&i1%5knrwm9+sw6-p4-58q4d(p='# SECURITY WARNING: don't run with debug turned on in production!DEBUG=TrueTEMPLATE_DEBUG=TrueALLOWED_HOSTS=[]# Application definitionINSTALLED_APPS=('django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','blog','sampledatahelper',)MIDDLEWARE_CLASSES=('django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',)ROOT_URLCONF='app.urls'WSGI_APPLICATION='app.wsgi.application'# Database# https://docs.djangoproject.com/en/1.6/ref/settings/#databasesDATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':os.path.join(BASE_DIR,'db.sqlite3'),}}# Internationalization# https://docs.djangoproject.com/en/1.6/topics/i18n/LANGUAGE_CODE='en-us'TIME_ZONE='UTC'USE_I18N=TrueUSE_L10N=TrueUSE_TZ=True# Static files (CSS, JavaScript, Images)# https://docs.djangoproject.com/en/1.6/howto/static-files/STATIC_URL='/static/'TEMPLATE_DIRS=[os.path.join(BASE_DIR,'templates'),]SAMPLEDATAHELPER_MODELS=[{'model':'blog.Post','number':100,},{'model':'blog.Tag','number':5,},]TEMPLATE_CONTEXT_PROCESSORS=('django.contrib.auth.context_processors.auth','blog.context_processors.tags',)USE_CDN=False
Y modificamos ligeramente el archivo templates/base.html, añadiendo una sidebar con el menú de Tags:
Y veremos aparecer el menú con todos los tags en todas nuestras páginas.
EJERCICIO: Dejo al lector un ejercicio de repaso: añadir una DetailView
para los blog.models.Tag, con su plantilla correspondiente, y enlazarlos
desde este menú que acabamos de crear. Para que os quede más chulo podéis usar
la librería Bootstra]; Podéis aprender lo asico en Bootstrap en 5 minutos ¿La
solución? En el tag 0.3.0-exercise del repositorio
git@github.com:magmax/django-blog.git.