Paginación con Django


Introducción

Las tareas de paginación son unas de las mas tediosas a la hora de programar un sitio Web. Django incluye herramientas para hacer todo este trabajo de una forma fácil y rápida.

En el siguiente tutorial explicaré un método para realizar paginación de noticias en una aplicación Web.

Este ejemplo esta basado en la version de desarrollo de Django en la fecha de hoy (0.97)

Creando nuestra aplicación

Vamos a suponer que tenemos una aplicación de noticias, la cual posee un modelo para almacenar las mismas:

models.py:

from django.db import models

class Noticias(models.Model):
    Titulo = models.CharField(maxlength=100)
    Cuerpo = models.TextField()
    Fecha_pub = models.DateField('Fecha', auto_now_add=True)
    Imagen = models.ImageField(upload_to= "noticias/%Y/%m/%d", blank=True)

    class Admin:
	list_display = ('Titulo', 'Fecha_pub')

    def  __str__(self):
	return self.Titulo

Para paginar utilizaremos el siguiente módulo de Python el cual puede estar en la raíz de la aplicación y ser incluído en esta con su include correspondiente:

paginator.py

from django.core.paginator import ObjectPaginator, InvalidPage

def Paginador(request, modelo, paginas):
	result_list = Paginator(modelo, paginas)
	try:
		page = int(request.GET.get('page')); #Tomamos el valor de parametro page, usando GET
	except:
		page = 1
	if (page < result_list.page(page)):
		pagina = result_list.page(page)
		Contexto = {'modelo': pagina.object_list, #Asignamos registros de la pagina
			 'page': page, #Pagina Actual
			 'pages': result_list.num_pages, #Cantidad de Paginas
			 'has_next': pagina.has_next(), #True si hay proxima pagina
			 'has_prev': pagina.has_previous(), #true si hay Pagina anterior
			 'next_page': page+1, #Proxima pagina
			 'prev_page': page-1, #Pagina Anterior
			 }
		return Contexto

Este modulo recibe dos argumentos: 1 es un objeto request, 2 un modelo (tabla), en este caso el modelo de las noticias. Como podemos ver la variable resul_list almacenaría solo tres registros de la tabla. “Contexto“ es un diccionario con todos los que nos interesa para realizar el paginado en la plantilla HTML.

También necesitaremos otra pequeña plantilla:

pagination.html:

{% if paginator.has_prev %}
	<a href="/noticias/?page={{ paginator.prev_page }}"><</a>
{% else %}
{% endif %}
Página {{paginator.page}} de {{paginator.pages}}
{% if paginator.has_next %}
	<a href="/noticias/?page={{ paginator.next_page }}">></a>
{% else %}
{% endif %}

Esta plantilla la debemos incluir en la plantilla HTML en la cual realmente queremos realizar el paginado.
Por último la vista que queremos muestre las noticias paginadas debe quedar de la siguiente manera:

views.py:

# importamos el modulo Paginador
from proyecto.Paginador import Paginador

def index(request):
	noticias = Noticias.objects.all().order_by('-Fecha_pub')
	pag = Paginador(request, noticias)
	plantilla = loader.get_template('noticias/noticias_list.html')
	c = RequestContext(request, {'noticia_list': pag['modelo'],
				     'request': request,
				     'paginator': pag,
	return HttpResponse(plantilla.render(c))

La función index es una función común,

  • Primero ordenamos el módulo Noticias por fecha para que se muestren primero las últimas noticias.
  • pag es un objeto del tipo Paginador el cual recibe dos argumentos y devuelve un diccionario.
  • Posteriormente pasamos los datos a la plantilla noticias_list.html
  • pag[‘modelo’] es el modelo(tabla) noticias con solamente 3 registros. Los que necesitamos.
  • pag es un diccionario con todos los datos necesarios para paginar.

Hasta aquí esta pequeña guía sobre cómo paginar. Espero sea de utilidad al lector, me gustaría recibir algunas opiniones al respecto y de ser posible también sugerencias, esta guía está implementada aquí

Anuncios

Una respuesta

  1. Buena, justo andaba buscando algo similar, me servira de guia, el unico problema es que no funciona el link al ejemplo y eso del return HttpResponse(plantilla.render(c)) ya no se usa parece, sino que directamente el atajo render_to_response …vere si lo puedo adaptar, saludos

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: