logo cosasdedevs

Paginación en Django con ListView

Paginación en Django con ListView

My Profile
Ene 12, 2020

Hace justo una semana conseguí publicar mi post número 11 así que decidí que era hora de añadir una paginación a mi blog y aprovechar ese conocimiento para crear un post de paginación con Django. Me sorprendió lo sencillo que es implementarlo como vais a ver, ¡here we go!

Para este ejemplo he creado un proyecto que va a paginar el listado de países existentes. He creado un modelo que contendrá el iso code y el nombre del país, como podéis ver aquí.

from django.db import models

class Country(models.Model):
    """Country model."""
    
    iso_code = models.CharField(max_length=2,unique=True)
    name = models.CharField(max_length=255,unique=True)

    class Meta:
        ordering = ('iso_code',)

    def __str__(self):
        return self.name

Una vez hecho esto he realizado las migraciones e importé el listado de países a mi base de datos.

Lo siguiente que haremos será crear la vista, para este caso utilizaremos la vista genérica ListView que nos facilitará el trabajo.

# Country view
from django.shortcuts import render
from django.views.generic import ListView

# Models
from countries.models import Country

class CountriesFeedView(ListView):
    template_name = 'countries/feed.html'
    model = Country
    paginate_by = 10
    context_object_name = 'countries'

Aquí lo que estamos haciendo es importar primero la vista genérica ListView y el modelo Country que es el que vamos a usar.

Después creamos la clase que extenderá de ListView, en este caso CountriesFeedView y añadimos la configuración.

template_name: Es la url donde se encuentra la plantilla que vamos a utilizar.
model: Nombre del modelo que utilizaremos, en este caso el modelo Country que es el que importamos anteriormente.
paginate_by: El número de objetos que se mostrarán por página, en este caso queremos que se muestren 10 países por página.
context_object_name: El nombre del objeto en la plantilla.

Una vez hecho esto Django nos proveerá del objecto page_obj que podremos utilizarlo en la plantilla para tratar la paginación. Este objeto contiene las siguientes utilidades:

page_obj.has_previous: Verifica si hay una página anterior.
page_obj.has_next: Verifica si hay una página posterior.
page_obj.previous_page_number: Devuelve el número de la página anterior.
page_obj.next_page_number: Devuelve el número de la siguiente página.
page_obj.number: Devuelve el número de la página actual.
page_obj.paginator.num_pages: Devuelve el número total de páginas.

Y aquí podéis ver como lo he implementado.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Countries list</title>
    <link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet">
    <style>
    * {
        font-family: "Roboto", Arial;
    }
    .main {
        max-width: 600px;
        margin: 0 auto;
        text-align: center;
    }
    .table-grid {
        display: grid;
        grid-template-columns: 1fr 1fr 3fr;
        border-top: 1px solid black;
        border-right: 1px solid black;
        margin-bottom: 1rem;
        text-align: left;
    }

    .table-grid > span {
        padding: 8px 4px;
        border-left: 1px solid black;
        border-bottom: 1px solid black;
    }
    a {
        text-decoration: none;
        color: #009FD2;
    }
    a:hover {
        text-decoration: underline;
        color: #0082AC;
    }
    </style>
</head>
<body>
    <div class="main">
        <div class="table-grid">
            <span>
                <strong>Id</strong>
            </span>
            <span>
                <strong>Iso code</strong>
            </span>
            <span>
                <strong>Country name</strong>
            </span>
        {% for country in countries %}
            <span>
                {{country.id}}
            </span>
            <span>
                {{country.iso_code}}
            </span>
            <span>
                {{country.name}}
            </span>
        {% endfor %}
        </div>
        <div class="pagination">
            <span class="step-links">
                {% if page_obj.has_previous %}
                    <a href="?page=1">&laquo; first</a>
                    <a href="?page={{ page_obj.previous_page_number }}">previous</a>
                {% endif %}

                <span class="current">
                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
                </span>

                {% if page_obj.has_next %}
                    <a href="?page={{ page_obj.next_page_number }}">next</a>
                    <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
                {% endif %}
            </span>
        </div>
    </div>
</body>
</html>

Para más información podéis acceder a la documentación de Django. Si queréis clonar el ejemplo del proyecto con la paginación implementada lo podéis hacer desde mi GitHub.

Recordad que cualquier duda podéis ponerla en los comentarios :)

808 vistas

Nos tomamos en serio tu privacidad

Utilizamos cookies propias y de terceros para mejorar la experiencia del usuario a través de su navegación. Si pulsas entendido aceptas su uso. Ver política de cookies.

🐍 Sígueme en Twitter

Si te gusta el contenido que subo y no quieres perderte nada, sígueme en Twitter y te avisaré cada vez que cree contenido nuevo 💪
Luego ¡Te sigo!