Avancé
🧠 Fondamentaux
30 XP
0 personnes ont réussi
Paginateur
Imagine une API qui renvoie 10 000 articles d'un coup. Le navigateur rame, la bande passante explose, l'experience utilisateur est catastrophique. La pagination est la solution : on decoupe les resultats en pages de 20 ou 50 elements, et le client navigue entre elles. C'est ce que font Google, Twitter, et toute API serieuse.
DRF propose plusieurs styles de pagination. Le plus courant est le PageNumberPagination : le client envoie un parametre page pour indiquer quelle page il veut.
La réponse paginee contient : - count : le nombre total d'éléments - next : le numéro de la page suivante (None si c'est la dernière) - previous : le numéro de la page précédente (None si c'est la première) - results : les éléments de la page courante
Tu vas créer une classe Paginator qui :
__init__(page_size) : definit le nombre d'éléments par page
paginate(data, page) : prend une liste et un numéro de page (commence a 1), retourne un dictionnaire avec count, next, previous, et results.
Si le numéro de page est invalide (0, negatif, ou au-dela du nombre de pages), retourne results vide avec les bonnes valeurs de count, next et previous.
Exemple :
p = Paginator(page_size=2) data = [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 5}]
p = Paginator(page_size=2)
data = [{'id': i} for i in range(1, 6)]
r = p.paginate(data, 1)
assert r['count'] == 5 and len(r['results']) == 2
assert r['next'] == 2 and r['previous'] is None
Dernière page
p = Paginator(page_size=2)
data = [{'id': i} for i in range(1, 6)]
r = p.paginate(data, 3)
assert len(r['results']) == 1 and r['next'] is None and r['previous'] == 2
Page du milieu
p = Paginator(page_size=2)
data = [{'id': i} for i in range(1, 6)]
r = p.paginate(data, 2)
assert len(r['results']) == 2 and r['next'] == 3 and r['previous'] == 1
Page invalide
p = Paginator(page_size=2)
data = [{'id': 1}, {'id': 2}]
r = p.paginate(data, 5)
assert r['results'] == [] and r['count'] == 2
+ 0 tests cachés
Indices (3 disponibles)
Solution officielle
import math
class Paginator:
def __init__(self, page_size=10):
self.page_size = page_size
def paginate(self, data, page=1):
total = len(data)
total_pages = math.ceil(total / self.page_size) if total > 0 else 0
if page < 1 or page > total_pages:
return {
'count': total,
'next': None,
'previous': None,
'results': [],
}
start = (page - 1) * self.page_size
end = start + self.page_size
results = data[start:end]
return {
'count': total,
'next': page + 1 if page < total_pages else None,
'previous': page - 1 if page > 1 else None,
'results': results,
}