def pseudo_ajouter_wtf(): form = FormWTFAjouterPseudo() if request.method == "POST": try: try: # Renvoie une erreur si la connexion est perdue. MaBaseDeDonnee().connexion_bd.ping(False) except Exception as erreur: flash( f"Dans Gestion pseudo ...terrible erreur, il faut connecter une base de donnée", "danger") print( f"Exception grave Classe constructeur GestionPseudo {erreur.args[0]}" ) raise MaBdErreurConnexion( f"{msg_erreurs['ErreurConnexionBD']['message']} {erreur.args[0]}" ) if form.validate_on_submit(): pseudo_wtf = form.pseudo_wtf.data pseudo = pseudo_wtf valeurs_insertion_dictionnaire = {"value_pseudo": pseudo} print("valeurs_insertion_dictionnaire ", valeurs_insertion_dictionnaire) strsql_insert_pseudo = """INSERT INTO t_pseudo (id_pseudo,pseudo) VALUES (NULL,%(value_pseudo)s)""" with MaBaseDeDonnee() as mconn_bd: mconn_bd.mabd_execute(strsql_insert_pseudo, valeurs_insertion_dictionnaire) flash(f"Données insérées !!", "success") print(f"Données insérées !!") # Pour afficher et constater l'insertion de la valeur, on affiche en ordre inverse. (DESC) return redirect( url_for('pseudo_afficher', order_by='DESC', id_pseudo_sel=0)) # ATTENTION à l'ordre des excepts, il est très important de respecter l'ordre. except pymysql.err.IntegrityError as erreur_pseudo_doublon: # Dérive "pymysql.err.IntegrityError" dans "MaBdErreurDoublon" fichier "erreurs/exceptions.py" # Ainsi on peut avoir un message d'erreur personnalisé. code, msg = erreur_pseudo_doublon.args flash(f"{error_codes.get(code, msg)} ", "warning") # OM 2020.04.16 ATTENTION à l'ordre des excepts, il est très important de respecter l'ordre. except (pymysql.err.OperationalError, pymysql.ProgrammingError, pymysql.InternalError, TypeError) as erreur_gest_pseudo_crud: code, msg = erreur_gest_pseudo_crud.args flash(f"{error_codes.get(code, msg)} ", "danger") flash( f"Erreur dans Gestion genres CRUD : {sys.exc_info()[0]} " f"{erreur_gest_pseudo_crud.args[0]} , " f"{erreur_gest_pseudo_crud}", "danger") return render_template("pseudo/pseudo_ajouter_wtf.html", form=form)
def genres_afficher(order_by, id_genre_sel): if request.method == "GET": try: try: # Renvoie une erreur si la connexion est perdue. MaBaseDeDonnee().connexion_bd.ping(False) except Exception as erreur: flash(f"Dans Gestion genres ...terrible erreur, il faut connecter une base de donnée", "danger") print(f"Exception grave Classe constructeur GestionGenres {erreur.args[0]}") raise MaBdErreurConnexion(f"{msg_erreurs['ErreurConnexionBD']['message']} {erreur.args[0]}") with MaBaseDeDonnee().connexion_bd.cursor() as mc_afficher: if order_by == "ASC" and id_genre_sel == 0: strsql_genres_afficher = """SELECT id_genre, intitule_genre FROM t_genre ORDER BY id_genre ASC""" mc_afficher.execute(strsql_genres_afficher) elif order_by == "ASC": # C'EST LA QUE VOUS ALLEZ DEVOIR PLACER VOTRE PROPRE LOGIQUE MySql # la commande MySql classique est "SELECT * FROM t_genre" # Pour "lever"(raise) une erreur s'il y a des erreurs sur les noms d'attributs dans la table # donc, je précise les champs à afficher # Constitution d'un dictionnaire pour associer l'id du genre sélectionné avec un nom de variable valeur_id_genre_selected_dictionnaire = {"value_id_genre_selected": id_genre_sel} strsql_genres_afficher = """SELECT id_genre, intitule_genre FROM t_genre WHERE id_genre = %(value_id_genre_selected)s""" mc_afficher.execute(strsql_genres_afficher, valeur_id_genre_selected_dictionnaire) else: strsql_genres_afficher = """SELECT id_genre, intitule_genre FROM t_genre ORDER BY id_genre DESC""" mc_afficher.execute(strsql_genres_afficher) data_genres = mc_afficher.fetchall() print("data_genres ", data_genres, " Type : ", type(data_genres)) # Différencier les messages si la table est vide. if not data_genres and id_genre_sel == 0: flash("""La table "t_genre" est vide. !!""", "warning") elif not data_genres and id_genre_sel > 0: # Si l'utilisateur change l'id_genre dans l'URL et que le genre n'existe pas, flash(f"Le genre demandé n'existe pas !!", "warning") else: # Dans tous les autres cas, c'est que la table "t_genre" est vide. # OM 2020.04.09 La ligne ci-dessous permet de donner un sentiment rassurant aux utilisateurs. flash(f"Données genres affichés !!", "success") except Exception as erreur: print(f"RGG Erreur générale. genres_afficher") # OM 2020.04.09 On dérive "Exception" par le "@obj_mon_application.errorhandler(404)" # fichier "run_mon_app.py" # Ainsi on peut avoir un message d'erreur personnalisé. flash(f"RGG Exception {erreur} genres_afficher", "danger") raise Exception(f"RGG Erreur générale. {erreur}") # raise MaBdErreurOperation(f"RGG Exception {msg_erreurs['ErreurNomBD']['message']} {erreur}") # Envoie la page "HTML" au serveur. return render_template("genres/genres_afficher.html", data=data_genres)
def films_genres_afficher(id_genre_sel): if request.method == "GET": try: try: # Renvoie une erreur si la connexion est perdue. MaBaseDeDonnee().connexion_bd.ping(False) except Exception as Exception_init_motifs_genres_afficher: code, msg = Exception_init_motifs_genres_afficher.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"Exception _init_motifs_genres_afficher problème de connexion BD : {sys.exc_info()[0]} " f"{Exception_init_motifs_genres_afficher.args[0]} , " f"{Exception_init_motifs_genres_afficher}", "danger") raise MaBdErreurConnexion(f"{msg_erreurs['ErreurConnexionBD']['message']} {erreur.args[0]}") with MaBaseDeDonnee().connexion_bd.cursor() as mc_afficher: strsql_genres_films_afficher_data = """ SELECT id_motif, motif, GROUP_CONCAT(nom_user) as GenresFilms FROM t_motif RIGHT JOIN t_facture ON t_facture.id_facture = t_motif.fk_facture LEFT JOIN t_user ON t_user.id_user = t_motif.fk_user GROUP BY id_motif""" if id_genre_sel == 0: # le paramètre 0 permet d'afficher tous les films # Sinon le paramètre représente la valeur de l'id du film mc_afficher.execute(strsql_genres_films_afficher_data) else: # Constitution d'un dictionnaire pour associer l'id du film sélectionné avec un nom de variable valeur_id_genre_selected_dictionnaire = {"value_id_genre_selected": id_genre_sel} # En MySql l'instruction HAVING fonctionne comme un WHERE... mais doit être associée à un GROUP BY # L'opérateur += permet de concaténer une nouvelle valeur à la valeur de gauche préalablement définie. strsql_genres_films_afficher_data += """ HAVING id_motif= %(value_id_genre_selected)s""" mc_afficher.execute(strsql_genres_films_afficher_data, valeur_id_genre_selected_dictionnaire) # Récupère les données de la requête. data_genres_films_afficher = mc_afficher.fetchall() print("data_genres ", data_genres_films_afficher, " Type : ", type(data_genres_films_afficher)) # Différencier les messages. if not data_genres_films_afficher and id_genre_sel == 0: flash("""La table "t_motif" est vide. !""", "warning") elif not data_genres_films_afficher and id_genre_sel > 0: # Si l'utilisateur change l'id_motif dans l'URL et qu'il ne correspond à aucun film flash(f"Le film {id_genre_sel} demandé n'existe pas !!", "warning") else: flash(f"Données films et genres affichés !!", "success") except Exception as Exception_films_genres_afficher: code, msg = Exception_films_genres_afficher.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"Exception films_genres_afficher : {sys.exc_info()[0]} " f"{Exception_films_genres_afficher.args[0]} , " f"{Exception_films_genres_afficher}", "danger") # Envoie la page "HTML" au serveur. return render_template("films_genres/films_genres_afficher.html", data=data_genres_films_afficher)
def facture_delete_wtf(): data_films_attribue_genre_delete = None btn_submit_del = None # L'utilisateur vient de cliquer sur le bouton "DELETE". Récupère la valeur de "id_facture" id_facture_delete = request.values['id_facture_btn_delete_html'] # Objet formulaire pour effacer le genre sélectionné. form_delete = FormWTFDeleteGenre() try: print(" on submit ", form_delete.validate_on_submit()) if request.method == "POST" and form_delete.validate_on_submit(): if form_delete.submit_btn_annuler.data: return redirect( url_for("factures_afficher", order_by="ASC", id_genre_sel=0)) if form_delete.submit_btn_conf_del.data: # Récupère les données afin d'afficher à nouveau # le formulaire "genres/facture_delete_wtf.html" lorsque le bouton "Etes-vous sur d'effacer ?" est cliqué. data_films_attribue_genre_delete = session[ 'data_films_attribue_genre_delete'] print("data_films_attribue_genre_delete ", data_films_attribue_genre_delete) flash(f"Effacer le genre de façon définitive de la BD !!!", "danger") # L'utilisateur vient de cliquer sur le bouton de confirmation pour effacer... # On affiche le bouton "Effacer genre" qui va irrémédiablement EFFACER le genre btn_submit_del = True if form_delete.submit_btn_del.data: valeur_delete_dictionnaire = { "value_id_facture": id_facture_delete } print("valeur_delete_dictionnaire ", valeur_delete_dictionnaire) str_sql_delete_destinataire = """DELETE FROM t_destinataire WHERE fk_facture = %(value_id_facture)s""" str_sql_delete_attente = """DELETE FROM t_attente WHERE fk_facture = %(value_id_facture)s""" str_sql_delete_motif = """DELETE FROM t_motif WHERE fk_facture = %(value_id_facture)s""" str_sql_delete_payement = """DELETE FROM t_payement WHERE fk_facture = %(value_id_facture)s""" str_sql_delete_rappel = """DELETE FROM t_rappel WHERE fk_facture = %(value_id_facture)s""" str_sql_delete_idgenre = """DELETE FROM t_facture WHERE id_facture = %(value_id_facture)s""" # Manière brutale d'effacer d'abord la "fk_facture", même si elle n'existe pas dans la "t_destinataire" # Ensuite on peut effacer le genre vu qu'il n'est plus "lié" (INNODB) dans la "t_destinataire" with MaBaseDeDonnee() as mconn_bd: mconn_bd.mabd_execute(str_sql_delete_destinataire, valeur_delete_dictionnaire) mconn_bd.mabd_execute(str_sql_delete_attente, valeur_delete_dictionnaire) mconn_bd.mabd_execute(str_sql_delete_motif, valeur_delete_dictionnaire) mconn_bd.mabd_execute(str_sql_delete_payement, valeur_delete_dictionnaire) mconn_bd.mabd_execute(str_sql_delete_rappel, valeur_delete_dictionnaire) mconn_bd.mabd_execute(str_sql_delete_idgenre, valeur_delete_dictionnaire) flash(f"Genre définitivement effacé !!", "success") print(f"Genre définitivement effacé !!") # afficher les données return redirect( url_for('factures_afficher', order_by="ASC", id_genre_sel=0)) if request.method == "GET": valeur_select_dictionnaire = { "value_id_facture": id_facture_delete } print(id_facture_delete, type(id_facture_delete)) # Requête qui affiche tous les films qui ont le genre que l'utilisateur veut effacer str_sql_genres_films_delete = """SELECT id_destinataire, destinataire, id_facture, numero_facture FROM t_destinataire INNER JOIN t_facture ON t_destinataire.fk_facture = t_facture.id_facture INNER JOIN t_user ON t_destinataire.fk_user = t_user.id_user WHERE fk_facture = %(value_id_facture)s""" mybd_curseur = MaBaseDeDonnee().connexion_bd.cursor() mybd_curseur.execute(str_sql_genres_films_delete, valeur_select_dictionnaire) data_films_attribue_genre_delete = mybd_curseur.fetchall() print("data_films_attribue_genre_delete...", data_films_attribue_genre_delete) # Nécessaire pour mémoriser les données afin d'afficher à nouveau # le formulaire "genres/facture_delete_wtf.html" lorsque le bouton "Etes-vous sur d'effacer ?" est cliqué. session[ 'data_films_attribue_genre_delete'] = data_films_attribue_genre_delete # Opération sur la BD pour récupérer "id_facture" et "numero_facture" de la "t_facture" str_sql_id_facture = "SELECT id_facture, numero_facture, somme, delai FROM t_facture WHERE id_facture = %(value_id_facture)s" mybd_curseur.execute(str_sql_id_facture, valeur_select_dictionnaire) # Une seule valeur est suffisante "fetchone()", # vu qu'il n'y a qu'un seul champ "nom genre" pour l'action DELETE data_nom_genre = mybd_curseur.fetchone() print("data_nom_genre ", data_nom_genre, " type ", type(data_nom_genre), " genre ", data_nom_genre["numero_facture"]) # Afficher la valeur sélectionnée dans le champ du formulaire "facture_delete_wtf.html" form_delete.numero_facture_delete_wtf.data = data_nom_genre[ "numero_facture"] # Le bouton pour l'action "DELETE" dans le form. "facture_delete_wtf.html" est caché. btn_submit_del = False # OM 2020.04.16 ATTENTION à l'ordre des excepts, il est très important de respecter l'ordre. except KeyError: flash( f"__KeyError dans facture_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") except ValueError: flash( f"Erreur dans facture_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]}", "danger") except (pymysql.err.OperationalError, pymysql.ProgrammingError, pymysql.InternalError, pymysql.err.IntegrityError, TypeError) as erreur_gest_genr_crud: code, msg = erreur_gest_genr_crud.args flash( f"attention : {error_codes.get(code, msg)} {erreur_gest_genr_crud} ", "danger") flash( f"Erreur dans facture_update_wtf : {sys.exc_info()[0]} " f"{erreur_gest_genr_crud.args[0]} , " f"{erreur_gest_genr_crud}", "danger") flash( f"__KeyError dans facture_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") return render_template( "factures/facture_delete_wtf.html", form_delete=form_delete, btn_submit_del=btn_submit_del, data_films_associes=data_films_attribue_genre_delete)
def facture_update_wtf(): # L'utilisateur vient de cliquer sur le bouton "EDIT". Récupère la valeur de "id_facture" id_facture_update = request.values['id_facture_btn_edit_html'] # Objet formulaire pour l'UPDATE form_update = FormWTFUpdateGenre() try: print(" on submit ", form_update.validate_on_submit()) if form_update.validate_on_submit(): # Récupèrer la valeur du champ depuis "facture_update_wtf.html" après avoir cliqué sur "SUBMIT". # Puis la convertir en lettres minuscules. numero_facture_update = form_update.numero_facture_update_wtf.data somme_update = form_update.somme_update_wtf.data delai_update = form_update.delai_update_wtf.data numero_facture_update = numero_facture_update.lower() somme_update = somme_update.lower() delai_update = delai_update.lower() valeur_update_dictionnaire = { "value_id_facture": id_facture_update, "value_numerous_facture": numero_facture_update, "value_somme": somme_update, "value_delai": delai_update } print("valeur_update_dictionnaire ", valeur_update_dictionnaire) str_sql_update_intitulegenre = """UPDATE t_facture SET numero_facture = %(value_numerous_facture)s WHERE id_facture = %(value_id_facture)s""" with MaBaseDeDonnee() as mconn_bd: mconn_bd.mabd_execute(str_sql_update_intitulegenre, valeur_update_dictionnaire) str_sql_update_intitulegenre = """UPDATE t_facture SET somme = %(value_somme)s WHERE id_facture = %(value_id_facture)s""" with MaBaseDeDonnee() as mconn_bd: mconn_bd.mabd_execute(str_sql_update_intitulegenre, valeur_update_dictionnaire) str_sql_update_intitulegenre = """UPDATE t_facture SET delai = %(value_delai)s WHERE id_facture = %(value_id_facture)s""" with MaBaseDeDonnee() as mconn_bd: mconn_bd.mabd_execute(str_sql_update_intitulegenre, valeur_update_dictionnaire) flash(f"Donnée mise à jour !!", "success") print(f"Donnée mise à jour !!") # afficher et constater que la donnée est mise à jour. # Affiche seulement la valeur modifiée, "ASC" et l'"id_facture_update" return redirect( url_for('genres_afficher', order_by="ASC", id_genre_sel=id_facture_update)) elif request.method == "GET": # Opération sur la BD pour récupérer "id_facture" et "numero_facture" de la "t_facture" str_sql_id_facture = "SELECT id_facture, numero_facture, somme, delai FROM t_facture WHERE id_facture = %(value_id_facture)s" valeur_select_dictionnaire = { "value_id_facture": id_facture_update } mybd_curseur = MaBaseDeDonnee().connexion_bd.cursor() mybd_curseur.execute(str_sql_id_facture, valeur_select_dictionnaire) # Une seule valeur est suffisante "fetchone()", vu qu'il n'y a qu'un seul champ "nom genre" pour l'UPDATE data_nom_genre = mybd_curseur.fetchone() print("data_nom_genre ", data_nom_genre, " type ", type(data_nom_genre), " genre ", data_nom_genre["numero_facture"]) # Afficher la valeur sélectionnée dans le champ du formulaire "facture_update_wtf.html" form_update.numero_facture_update_wtf.data = data_nom_genre[ "numero_facture"] form_update.somme_update_wtf.data = data_nom_genre["somme"] form_update.delai_update_wtf.data = data_nom_genre["delai"] # OM 2020.04.16 ATTENTION à l'ordre des excepts, il est très important de respecter l'ordre. except KeyError: flash( f"__KeyError dans facture_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") except ValueError: flash( f"Erreur dans facture_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]}", "danger") except (pymysql.err.OperationalError, pymysql.ProgrammingError, pymysql.InternalError, pymysql.err.IntegrityError, TypeError) as erreur_gest_genr_crud: code, msg = erreur_gest_genr_crud.args flash( f"attention : {error_codes.get(code, msg)} {erreur_gest_genr_crud} ", "danger") flash( f"Erreur dans facture_update_wtf : {sys.exc_info()[0]} " f"{erreur_gest_genr_crud.args[0]} , " f"{erreur_gest_genr_crud}", "danger") flash( f"__KeyError dans facture_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") return render_template("factures/facture_update_wtf.html", form_update=form_update)
def demo_select_wtf(): genre_selectionne = None # Objet formulaire pour montrer une liste déroulante basé sur la table "t_genre" form_demo = DemoFormSelectWTF() try: if request.method == "POST" and form_demo.submit_btn_ok_dplist_genre.data: if form_demo.submit_btn_ok_dplist_genre.data: print("Genre sélectionné : ", form_demo.genres_dropdown_wtf.data) genre_selectionne = form_demo.genres_dropdown_wtf.data form_demo.genres_dropdown_wtf.choices = session[ 'genre_val_list_dropdown'] if request.method == "GET": with MaBaseDeDonnee().connexion_bd.cursor() as mc_afficher: strsql_genres_afficher = """SELECT id_genre, nom_famille FROM t_genre ORDER BY id_genre ASC""" mc_afficher.execute(strsql_genres_afficher) data_genres = mc_afficher.fetchall() print("demo_select_wtf data_genres ", data_genres, " Type : ", type(data_genres)) """ Préparer les valeurs pour la liste déroulante de l'objet "form_demo" la liste déroulante est définie dans le "wtf_forms_demo_select.py" le formulaire qui utilise la liste déroulante "zzz_essais_om_104/demo_form_select_wtf.html" """ genre_val_list_dropdown = [] for i in data_genres: genre_val_list_dropdown.append(i['nom_famille']) # Aussi possible d'avoir un id numérique et un texte en correspondance # genre_val_list_dropdown = [(i["id_genre"], i["nom_famille"]) for i in data_genres] print("genre_val_list_dropdown ", genre_val_list_dropdown) form_demo.genres_dropdown_wtf.choices = genre_val_list_dropdown session['genre_val_list_dropdown'] = genre_val_list_dropdown # Ceci est simplement une petite démo. on fixe la valeur PRESELECTIONNEE de la liste form_demo.genres_dropdown_wtf.data = "philosophique" genre_selectionne = form_demo.genres_dropdown_wtf.data print("genre choisi dans la liste :", genre_selectionne) session['genre_selectionne_get'] = genre_selectionne # OM 2020.04.16 ATTENTION à l'ordre des excepts, il est très important de respecter l'ordre. except KeyError: flash( f"__KeyError dans wtf_forms_demo_select : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") except ValueError: flash( f"Erreur dans wtf_forms_demo_select : {sys.exc_info()[0]} {sys.exc_info()[1]}", "danger") except (pymysql.err.OperationalError, pymysql.ProgrammingError, pymysql.InternalError, pymysql.err.IntegrityError, TypeError) as erreur_gest_genr_crud: code, msg = erreur_gest_genr_crud.args flash( f"attention : {error_codes.get(code, msg)} {erreur_gest_genr_crud} ", "danger") flash( f"Erreur dans wtf_forms_demo_select : {sys.exc_info()[0]} " f"{erreur_gest_genr_crud.args[0]} , " f"{erreur_gest_genr_crud}", "danger") flash( f"__KeyError dans wtf_forms_demo_select : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") return render_template("zzz_essais_om_104/demo_form_select_wtf.html", form=form_demo, genre_selectionne=genre_selectionne)
def genres_films_afficher_data(valeur_id_genre_selected_dict): print("valeur_id_genre_selected_dict...", valeur_id_genre_selected_dict) try: strsql_film_selected = """SELECT id_motif, motif, GROUP_CONCAT(id_user) as GenresFilms FROM t_motif INNER JOIN t_facture ON t_facture.id_facture = t_motif.fk_facture INNER JOIN t_user ON t_user.id_user = t_motif.fk_user WHERE id_motif = %(value_id_genre_selected)s""" strsql_genres_films_non_attribues = """SELECT id_user, nom_user FROM t_user WHERE id_user not in(SELECT id_user as idGenresFilms FROM t_motif INNER JOIN t_facture ON t_facture.id_facture = t_motif.fk_facture INNER JOIN t_user ON t_user.id_user = t_motif.fk_user WHERE id_motif = %(value_id_genre_selected)s)""" strsql_genres_films_attribues = """SELECT id_motif, motif FROM t_motif INNER JOIN t_facture ON t_facture.id_facture = t_motif.fk_facture INNER JOIN t_user ON t_user.id_user = t_motif.fk_user WHERE id_motif = %(value_id_genre_selected)s""" # Du fait de l'utilisation des "context managers" on accède au curseur grâce au "with". with MaBaseDeDonnee().connexion_bd.cursor() as mc_afficher: # Envoi de la commande MySql mc_afficher.execute(strsql_genres_films_non_attribues, valeur_id_genre_selected_dict) # Récupère les données de la requête. data_genres_films_non_attribues = mc_afficher.fetchall() # Affichage dans la console print("genres_films_afficher_data ----> data_genres_films_non_attribues ", data_genres_films_non_attribues, " Type : ", type(data_genres_films_non_attribues)) # Envoi de la commande MySql mc_afficher.execute(strsql_film_selected, valeur_id_genre_selected_dict) # Récupère les données de la requête. data_film_selected = mc_afficher.fetchall() # Affichage dans la console print("data_film_selected ", data_film_selected, " Type : ", type(data_film_selected)) # Envoi de la commande MySql mc_afficher.execute(strsql_genres_films_attribues, valeur_id_genre_selected_dict) # Récupère les données de la requête. data_genres_films_attribues = mc_afficher.fetchall() # Affichage dans la console print("data_genres_films_attribues ", data_genres_films_attribues, " Type : ", type(data_genres_films_attribues)) # Retourne les données des "SELECT" return data_film_selected, data_genres_films_non_attribues, data_genres_films_attribues except pymysql.Error as pymysql_erreur: code, msg = pymysql_erreur.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"pymysql.Error Erreur dans genres_films_afficher_data : {sys.exc_info()[0]} " f"{pymysql_erreur.args[0]} , " f"{pymysql_erreur}", "danger") except Exception as exception_erreur: code, msg = exception_erreur.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"Exception Erreur dans genres_films_afficher_data : {sys.exc_info()[0]} " f"{exception_erreur.args[0]} , " f"{exception_erreur}", "danger") except pymysql.err.IntegrityError as IntegrityError_genres_films_afficher_data: code, msg = IntegrityError_genres_films_afficher_data.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"pymysql.err.IntegrityError Erreur dans genres_films_afficher_data : {sys.exc_info()[0]} " f"{IntegrityError_genres_films_afficher_data.args[0]} , " f"{IntegrityError_genres_films_afficher_data}", "danger")
def update_genre_film_selected(): if request.method == "POST": try: # Récupère l'id du film sélectionné id_genre_selected = session['session_id_motif_genres_edit'] print("session['session_id_motif_genres_edit'] ", session['session_id_motif_genres_edit']) # Récupère la liste des genres qui ne sont pas associés au film sélectionné. old_lst_data_genres_films_non_attribues = session['session_lst_data_genres_films_non_attribues'] print("old_lst_data_genres_films_non_attribues ", old_lst_data_genres_films_non_attribues) # Récupère la liste des genres qui sont associés au film sélectionné. old_lst_data_genres_films_attribues = session['session_lst_data_genres_films_old_attribues'] print("old_lst_data_genres_films_old_attribues ", old_lst_data_genres_films_attribues) # Effacer toutes les variables de session. session.clear() # Récupère ce que l'utilisateur veut modifier comme genres dans le composant "tags-selector-tagselect" # dans le fichier "genres_films_modifier_tags_dropbox.html" new_lst_str_genres_films = request.form.getlist('name_select_tags') print("new_lst_str_genres_films ", new_lst_str_genres_films) # OM 2021.05.02 Exemple : Dans "name_select_tags" il y a ['4','65','2'] # On transforme en une liste de valeurs numériques. [4,65,2] new_lst_int_motif_old = list(map(int, new_lst_str_genres_films)) print("new_lst_motif ", new_lst_int_motif_old, "type new_lst_motif ", type(new_lst_int_motif_old)) # Pour apprécier la facilité de la vie en Python... "les ensembles en Python" # https://fr.wikibooks.org/wiki/Programmation_Python/Ensembles # OM 2021.05.02 Une liste de "id_motif" qui doivent être effacés de la table intermédiaire "t_motif". lst_diff_genres_delete_b = list( set(old_lst_data_genres_films_attribues) - set(new_lst_int_motif_old)) print("lst_diff_genres_delete_b ", lst_diff_genres_delete_b) # Une liste de "id_motif" qui doivent être ajoutés à la "t_motif" lst_diff_genres_insert_a = list( set(new_lst_int_motif_old) - set(old_lst_data_genres_films_attribues)) print("lst_diff_genres_insert_a ", lst_diff_genres_insert_a) # SQL pour insérer une nouvelle association entre # "fk_facture"/"id_motif" et "fk_user"/"id_motif" dans la "t_motif" strsql_insert_motif = """INSERT INTO t_motif (id_motif, fk_user, fk_facture) VALUES (NULL, %(value_fk_user)s, %(value_fk_facture)s)""" # SQL pour effacer une (des) association(s) existantes entre "id_motif" et "id_motif" dans la "t_motif" strsql_delete_genre_film = """DELETE FROM t_motif WHERE fk_user = %(value_fk_user)s AND fk_facture = %(value_fk_facture)s""" with MaBaseDeDonnee() as mconn_bd: # Pour le film sélectionné, parcourir la liste des genres à INSÉRER dans la "t_motif". # Si la liste est vide, la boucle n'est pas parcourue. for id_motif_ins in lst_diff_genres_insert_a: # Constitution d'un dictionnaire pour associer l'id du film sélectionné avec un nom de variable # et "id_motif_ins" (l'id du genre dans la liste) associé à une variable. valeurs_film_sel_genre_sel_dictionnaire = {"value_fk_facture": id_genre_selected, "value_fk_user": id_motif_ins} mconn_bd.mabd_execute(strsql_insert_motif, valeurs_film_sel_genre_sel_dictionnaire) # Pour le film sélectionné, parcourir la liste des genres à EFFACER dans la "t_motif". # Si la liste est vide, la boucle n'est pas parcourue. for id_motif_del in lst_diff_genres_delete_b: # Constitution d'un dictionnaire pour associer l'id du film sélectionné avec un nom de variable # et "id_motif_del" (l'id du genre dans la liste) associé à une variable. valeurs_film_sel_genre_sel_dictionnaire = {"value_fk_facture": id_genre_selected, "value_fk_user": id_motif_del} # Du fait de l'utilisation des "context managers" on accède au curseur grâce au "with". # la subtilité consiste à avoir une méthode "mabd_execute" dans la classe "MaBaseDeDonnee" # ainsi quand elle aura terminé l'insertion des données le destructeur de la classe "MaBaseDeDonnee" # sera interprété, ainsi on fera automatiquement un commit mconn_bd.mabd_execute(strsql_delete_genre_film, valeurs_film_sel_genre_sel_dictionnaire) except Exception as Exception_update_genre_film_selected: code, msg = Exception_update_genre_film_selected.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"Exception update_genre_film_selected : {sys.exc_info()[0]} " f"{Exception_update_genre_film_selected.args[0]} , " f"{Exception_update_genre_film_selected}", "danger") # Après cette mise à jour de la table intermédiaire "t_motif", # on affiche les films et le(urs) genre(s) associé(s). return redirect(url_for('films_genres_afficher', id_genre_sel=id_genre_selected))
def edit_motif_selected(): if request.method == "GET": try: with MaBaseDeDonnee().connexion_bd.cursor() as mc_afficher: strsql_genres_afficher = """SELECT id_user, nom_user FROM t_user ORDER BY id_user""" mc_afficher.execute(strsql_genres_afficher) data_genres_all = mc_afficher.fetchall() print("dans edit_motif_selected ---> data_genres_all", data_genres_all) # Récupère la valeur de "id_motif" du formulaire html "films_genres_afficher.html" # l'utilisateur clique sur le bouton "Modifier" et on récupère la valeur de "id_motif" # grâce à la variable "id_motif_genres_edit_html" dans le fichier "films_genres_afficher.html" # href="{{ url_for('edit_motif_selected', id_motif_genres_edit_html=row.id_motif) }}" id_motif_genres_edit = request.values['id_motif_genres_edit_html'] # Mémorise l'id du film dans une variable de session # (ici la sécurité de l'application n'est pas engagée) # il faut éviter de stocker des données sensibles dans des variables de sessions. session['session_id_motif_genres_edit'] = id_motif_genres_edit # Constitution d'un dictionnaire pour associer l'id du film sélectionné avec un nom de variable valeur_id_genre_selected_dictionnaire = {"value_id_genre_selected": id_motif_genres_edit} # Récupère les données grâce à 3 requêtes MySql définie dans la fonction genres_films_afficher_data # 1) Sélection du film choisi # 2) Sélection des genres "déjà" attribués pour le film. # 3) Sélection des genres "pas encore" attribués pour le film choisi. # ATTENTION à l'ordre d'assignation des variables retournées par la fonction "genres_films_afficher_data" data_genre_film_selected, data_genres_films_non_attribues, data_genres_films_attribues = \ genres_films_afficher_data(valeur_id_genre_selected_dictionnaire) print(data_genre_film_selected) lst_data_film_selected = [item['id_motif'] for item in data_genre_film_selected] print("lst_data_film_selected ", lst_data_film_selected, type(lst_data_film_selected)) # Dans le composant "tags-selector-tagselect" on doit connaître # les genres qui ne sont pas encore sélectionnés. lst_data_genres_films_non_attribues = [item['id_user'] for item in data_genres_films_non_attribues] session['session_lst_data_genres_films_non_attribues'] = lst_data_genres_films_non_attribues print("lst_data_genres_films_non_attribues ", lst_data_genres_films_non_attribues, type(lst_data_genres_films_non_attribues)) # Dans le composant "tags-selector-tagselect" on doit connaître # les genres qui sont déjà sélectionnés. lst_data_genres_films_old_attribues = [item['id_user'] for item in data_genres_films_attribues] session['session_lst_data_genres_films_old_attribues'] = lst_data_genres_films_old_attribues print("lst_data_genres_films_old_attribues ", lst_data_genres_films_old_attribues, type(lst_data_genres_films_old_attribues)) print(" data data_genre_film_selected", data_genre_film_selected, "type ", type(data_genre_film_selected)) print(" data data_genres_films_non_attribues ", data_genres_films_non_attribues, "type ", type(data_genres_films_non_attribues)) print(" data_genres_films_attribues ", data_genres_films_attribues, "type ", type(data_genres_films_attribues)) # Extrait les valeurs contenues dans la table "t_users", colonne "intitule_genre" # Le composant javascript "tagify" pour afficher les tags n'a pas besoin de l'id_motif lst_data_genres_films_non_attribues = [item['nom_user'] for item in data_genres_films_non_attribues] print("lst_all_genres gf_edit_motif_selected ", lst_data_genres_films_non_attribues, type(lst_data_genres_films_non_attribues)) except Exception as Exception_edit_motif_selected: code, msg = Exception_edit_motif_selected.args flash(f"{error_codes.get(code, msg)} ", "danger") flash(f"Exception edit_motif_selected : {sys.exc_info()[0]} " f"{Exception_edit_motif_selected.args[0]} , " f"{Exception_edit_motif_selected}", "danger") return render_template("films_genres/films_genres_modifier_tags_dropbox.html", data_genres=data_genres_all, data_film_selected=data_genre_film_selected, data_genres_attribues=data_genres_films_attribues, data_genres_non_attribues=data_genres_films_non_attribues)
def personne_update_wtf(): # L'utilisateur vient de cliquer sur le bouton "EDIT". Récupère la valeur de "id_genre" id_personne_update = request.values['id_personne_btn_edit_html'] # Objet formulaire pour l'UPDATE form_update = FormWTFUpdatePersonne() try: print(" on submit ", form_update.validate_on_submit()) if form_update.validate_on_submit(): # Récupèrer la valeur du champ depuis "genre_update_wtf.html" après avoir cliqué sur "SUBMIT". # Puis la convertir en lettres minuscules. name_personne_update_wtf = form_update.nom_personne_update_wtf.data firstName_personne_update_wtf = form_update.prenom_personne_update_wtf.data birthDate_personne_update_wtf = form_update.dateDeNaissance_personne_update_wtf.data name_personne_update = name_personne_update_wtf.capitalize() firstName_personne_update = firstName_personne_update_wtf.capitalize( ) birthDate_personne_update = birthDate_personne_update_wtf valeur_update_dictionnaire = { "value_id_update": id_personne_update, "value_name_update": name_personne_update, "value_firstName_update": firstName_personne_update, "value_birthDate_update": birthDate_personne_update } print("valeur_update_dictionnaire ", valeur_update_dictionnaire) str_sql_update_personne = """UPDATE `t_personne` SET `pers_nom` = %(value_name_update)s, `pers_prenom` = %(value_firstName_update)s, `pers_dateDeNaissance` = %(value_birthDate_update)s WHERE `t_personne`.`id_personne` = %(value_id_update)s;""" #str_sql_update_personne = """UPDATE `t_personne` SET `pers_nom` = 'Wead', `pers_prenom` = 'asd', `pers_dateDeNaissance` = '1990-04-13' WHERE `t_personne`.`id_personne` = 16;""" with MaBaseDeDonnee() as mconn_bd: mconn_bd.mabd_execute(str_sql_update_personne, valeur_update_dictionnaire) flash(f"Donnée mise à jour !!", "success") print(f"Donnée mise à jour !!") # afficher et constater que la donnée est mise à jour. # Affiche seulement la valeur modifiée, "ASC" et l'"id_genre_update" return redirect( url_for('personne_afficher', order_by="ASC", id_personne_sel=id_personne_update)) elif request.method == "GET": # Opération sur la BD pour récupérer "id_genre" et "intitule_genre" de la "t_genre" str_sql_id_personne = """SELECT id_personne, pers_nom, pers_prenom, pers_dateDeNaissance FROM t_personne WHERE id_personne = %(value_id_personne)s""" valeur_select_dictionnaire = { "value_id_personne": id_personne_update } mybd_curseur = MaBaseDeDonnee().connexion_bd.cursor() mybd_curseur.execute(str_sql_id_personne, valeur_select_dictionnaire) # Une seule valeur est suffisante "fetchone()", vu qu'il n'y a qu'un seul champ "nom genre" pour l'UPDATE data_personne = mybd_curseur.fetchone() print("data_personne ", data_personne, " type ", type(data_personne), " personne ", data_personne["pers_nom"]) # Afficher la valeur sélectionnée dans le champ du formulaire "genre_update_wtf.html" form_update.nom_personne_update_wtf.data = data_personne[ "pers_nom"] form_update.prenom_personne_update_wtf.data = data_personne[ "pers_prenom"] form_update.dateDeNaissance_personne_update_wtf.data = data_personne[ "pers_dateDeNaissance"] # OM 2020.04.16 ATTENTION à l'ordre des excepts, il est très important de respecter l'ordre. except KeyError: flash( f"__KeyError dans prenom_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") except ValueError: flash( f"Erreur dans prenom_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]}", "danger") except (pymysql.err.OperationalError, pymysql.ProgrammingError, pymysql.InternalError, pymysql.err.IntegrityError, TypeError) as erreur_gest_pers_crud: code, msg = erreur_gest_pers_crud.args flash( f"attention : {error_codes.get(code, msg)} {erreur_gest_pers_crud} ", "danger") flash( f"Erreur dans personne_update_wtf : {sys.exc_info()[0]} " f"{erreur_gest_pers_crud.args[0]} , " f"{erreur_gest_pers_crud}", "danger") flash( f"__KeyError dans personne_update_wtf : {sys.exc_info()[0]} {sys.exc_info()[1]} {sys.exc_info()[2]}", "danger") return render_template("personne/personne_update_wtf.html", form_update=form_update)