En la parte anterior dejamos la base de datos lista, es momento de crear las plantillas para visualizar estos datos.
Lo primero que haremos es configurar el directorio donde estaran guardas las plantillas. Creamos el directorio templates en la raíz del proyecto y editamos el archivo settings.py.
- .....
- import os
-
- TEMPLATE_DIRS = (
- os.path.join(os.path.dirname(__file__) ,"templates"),
- )
- ....
.....
import os
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__) ,"templates"),
)
....
Así el script puede encontrar el directorio templates aun cuando cambiemos de ubicación la carpeta del proyecto. Ahora editamos el archivo urls.py para incluir la url a la pagina.
- ....
- urlpatterns = patterns('',
- (r'^$', 'blog.views.index'),
- ....
- )
....
urlpatterns = patterns('',
(r'^$', 'blog.views.index'),
....
)
Con esto le decimos a django que toda petición hecha a la raíz del blog sera manejada por la función index ubicada en el archivo
views, la cual luce así:
- from django.shortcuts import render_to_response
-
- def index(request):
- return render_to_response("index.html")
from django.shortcuts import render_to_response
def index(request):
return render_to_response("index.html")
Al visitar la raíz del sitio, django llamara la función index pasando como argumento un objeto
request que contiene información sobre la solicitud (datos POST y GET entre otros). La función index realizar algún proceso y retornar un objeto
response.
Si iniciamos el servidor de desarrollo y entramos a la dirección localhost:8000 veremos un mensaje de error como el de la imagen ya que la plantilla
index.html aun no existe, así que manos a la obra.
- <!DOCTYPE HTML>
- <html lang="es-ES">
- <head>
- <title>Mi Blog</title>
- </head>
- <body>
- <!-- hasta aquí siempre es igual -->
- <h1>Hola Django</h1>
- </body>
<!DOCTYPE HTML>
<html lang="es-ES">
<head>
<title>Mi Blog</title>
</head>
<body>
<!-- hasta aquí siempre es igual -->
<h1>Hola Django</h1>
</body>
No muy útil, pero por el momento es todo lo que necesitamos. Imagine que creamos otras plantillas para post individuales, contacto, faq, quejas... debemos repetir la cabecera en cada una de ellas.
El
sistema de plantillas de django permite crear
plantillas base con bloques que luego pueden ser reemplazados por las plantillas que heredan de ésta; para tal efecto creamos la plantilla base.html:
- <!DOCTYPE HTML>
- <html lang="es-ES">
- <head>
- <title>Mi Blog</title>
- </head>
- <body>
- {% block content %}
- {% endblock %}
- </body>
<!DOCTYPE HTML>
<html lang="es-ES">
<head>
<title>Mi Blog</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
Y editamos la plantilla index.html para que extienda base.html:
- {% extends "base.html" %}
- {% block content %}
- <h1>Hola Django</h1>
- {% endblock %}
{% extends "base.html" %}
{% block content %}
<h1>Hola Django</h1>
{% endblock %}
Ok, teniendo una idea general del sistema de plantillas, seguimos con la pagina inicial del blog empezando por editar el archivo views.py.
- from django.shorcuts import render_to_response
- from blog.models import Post
-
- def index(request):
-
- posts = Post.objects.filter()[:5]
- return render_to_response("index.html", locals())
from django.shorcuts import render_to_response
from blog.models import Post
def index(request):
# recuperamos 5 primeras entradas
posts = Post.objects.filter()[:5]
return render_to_response("index.html", locals())
Cada vez que visitemos a la raíz del blog se consultaran los primeros 5 post y se pasaran a la plantilla index.
- {
- {% extends "base.html" %}
-
- {% block content %}
- {% for post in posts %}
- <h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
- <p>{{ post.pub_date}}</p>
- {{ post.body }}
- {
- {% for tag in post.tags.filter %}
- <a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
- {% endfor %}
- {% endfor %}
- {% endblock %}
{# plantilla index.html #}
{% extends "base.html" %}
{% block content %}
{% for post in posts %}
<h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
<p>{{ post.pub_date}}</p>
{{ post.body }}
{# esto no es muy eficiente* #}
{% for tag in post.tags.filter %}
<a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
{% endfor %}
{% endfor %}
{% endblock %}
* Extraer las etiquetas de esta forma no es eficiente ya que al llamar a filter (5 veces) se hace una nueva consulta a la base de datos, algunas soluciones se pueden
encontrar aquí.
Con esto la pagina principal esta lista. Sigamos con la pagina individual, veremos que al trabajar con django se sigue mas o menos el mismo patrón:
-
- urlpatterns = patterns('',
- (r'^$', 'blog.views.index'),
-
- (r'^post/(?P<id>\d+)$', 'blog.views.single'),
- )
# archivo urls.py
urlpatterns = patterns('',
(r'^$', 'blog.views.index'),
# expresión regular que captura el numero después de post/
(r'^post/(?P<id>\d+)$', 'blog.views.single'),
)
-
- ...
-
- def single(request, id=0):
-
- post = Post.objects.get(id=int(id))
-
- return render_to_response("single.html", locals())
# Archivo views.py
...
# la funcion recibe el numero capturado
def single(request, id=0):
# recuperar post según id
post = Post.objects.get(id=int(id))
return render_to_response("single.html", locals())
- {
- {% block content %}
- <h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
- <p>{{ post.pub_date}}</p>
- {{ post.body }}
- {
- {% for tag in post.tags.filter %}
- <a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
- {% endfor %}
- {% endblock %}
{# plantilla single.html #}
{% block content %}
<h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
<p>{{ post.pub_date}}</p>
{{ post.body }}
{# esto no es muy eficiente* #}
{% for tag in post.tags.filter %}
<a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
{% endfor %}
{% endblock %}
Notan algo raro? el código de
single.html e
index.html luce muy similar; podemos eliminar el código repetido moviéndolo a otra plantilla (article.html) que luego
incluimos en estas.
- {
- </div>
- <h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
- <p>{{ post.pub_date}}</p>
- {{ post.body }}
- {
- {% for tag in post.tags.filter %}
- <a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
- {% endfor %}
- </div>
{# plantilla article.html #}
</div>
<h1><a href="/{{ post.id }}">{{ post.title }}</a></h1>
<p>{{ post.pub_date}}</p>
{{ post.body }}
{# esto no es muy eficiente* #}
{% for tag in post.tags.filter %}
<a href="/tags/{{ tag.tag }}">{{ tag.tag }}</a>
{% endfor %}
</div>
Ahora editamos las plantillas index.html y single.html para que utilicen article.html.
- {
- {% extends 'base.html' %}
-
- {% block main_content %}
- {% for post in posts %}
- {
- {% include 'include/article.html' with post=post %}
- {% endfor %}
-
- {% endblock %}
{# plantilla inde.html #}
{% extends 'base.html' %}
{% block main_content %}
{% for post in posts %}
{# pasamos la variable post como argumento #}
{% include 'include/article.html' with post=post %}
{% endfor %}
{% endblock %}
- {
- {% extends 'base.html' %}
-
- {% block main_content %}
- {% include 'include/article.html' %}
- {% endblock %}
{# plantilla single.html #}
{% extends 'base.html' %}
{% block main_content %}
{% include 'include/article.html' %}
{% endblock %}
Con esto damos por terminado esta parte. No se olviden de comentar.
P.D.: Procurare tener la próxima parte mas rápido.