IT-Stock/app/categories_arbre.py

37 lines
1.4 KiB
Python
Raw Permalink Normal View History

"""
Utilitaires de parcours de l'arborescence de catégories (profondeur
illimitée). Partagés entre le routeur categories (affichage de l'arbre) et
le routeur materiels (construction du <select> indenté).
"""
from sqlmodel import Session, select
from app.models import Categorie
def categories_racines(session: Session) -> list[Categorie]:
"""Catégories de premier niveau (sans parent)."""
return list(session.exec(select(Categorie).where(Categorie.parent_id.is_(None))).all())
def aplatir(categories: list[Categorie], profondeur: int = 0) -> list[tuple[int, Categorie]]:
"""Aplatit l'arborescence en une liste (profondeur, categorie), dans
l'ordre d'affichage (chaque nœud juste avant ses enfants). Sert à
construire un <select> indenté sans avoir besoin de JavaScript."""
resultat: list[tuple[int, Categorie]] = []
for categorie in categories:
resultat.append((profondeur, categorie))
resultat.extend(aplatir(categorie.enfants, profondeur + 1))
return resultat
def ids_sous_arbre(categorie: Categorie) -> set[int]:
"""L'id de cette catégorie et de tous ses descendants, à n'importe
quelle profondeur. Sert au filtre "cette catégorie" sur /materiels :
on veut aussi les matériels rattachés à ses sous-catégories, pas
seulement à elle-même."""
ids = {categorie.id}
for enfant in categorie.enfants:
ids |= ids_sous_arbre(enfant)
return ids