from flask import Blueprint from flask_admin.contrib.sqla import ModelView from flask_admin import BaseView, expose from app import db, admin from app.models import Matiere, SousCategorie, Texte from flask_ckeditor import CKEditorField from wtforms import StringField, TextAreaField from bleach import clean from bs4 import BeautifulSoup bp = Blueprint('custom_admin', __name__, url_prefix='/admin') def sanitize_html(html_content): # TRÈS PERMISSIF - UNIQUEMENT POUR LE TEST return clean(html_content, tags=[], attributes={}, strip=False) class MatiereView(ModelView): column_list = ('nom', 'sous_categories') # Colonnes à afficher dans la liste form_columns = ('nom',) class SousCategorieView(ModelView): column_list = ('nom', 'matiere') form_columns = ('nom', 'matiere') #form_overrides = dict(nom=StringField) form_args = { # Amélioration de la sélection de la matière 'matiere': { 'query_factory': lambda: Matiere.query.order_by(func.lower(Matiere.nom)) #Tri insensible à la casse } } def on_model_change(self, form, model, is_created): # Vérification de l'unicité (nom, matiere_id) *avant* l'insertion/mise à jour if is_created: existing = SousCategorie.query.filter( func.lower(SousCategorie.nom) == func.lower(form.nom.data), SousCategorie.matiere_id == form.matiere.data.id ).first() if existing: raise ValueError("Cette sous-catégorie existe déjà pour cette matière.") else: #Mise à jour existing = SousCategorie.query.filter( func.lower(SousCategorie.nom) == func.lower(form.nom.data), SousCategorie.matiere_id == form.matiere.data.id, SousCategorie.id != model.id ).first() if existing: raise ValueError("Cette sous-catégorie existe déjà pour cette matière.") class TexteView(ModelView): column_list = ('titre', 'sous_categorie') form_columns = ('titre', 'contenu', 'sous_categorie') form_overrides = dict(contenu=CKEditorField) form_args = { 'sous_categorie': { 'query_factory': lambda: SousCategorie.query.join(Matiere).order_by(func.lower(Matiere.nom), func.lower(SousCategorie.nom)) } } def on_model_change(self, form, model, is_created): model.contenu = sanitize_html(form.contenu.data) admin.add_view(MatiereView(Matiere, db.session)) admin.add_view(SousCategorieView(SousCategorie, db.session)) admin.add_view(TexteView(Texte, db.session))