<?xml
version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="https://edualc.be/spip.php?page=backend.xslt" ?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom"
>

<channel xml:lang="fr">
	<title>Edualc's Blog</title>
	<link>https://edualc.be/</link>
	<description></description>
	<language>fr</language>
	<generator>SPIP - www.spip.net</generator>
	<atom:link href="https://edualc.be/spip.php?page=backend" rel="self" type="application/rss+xml" />



	

	



<item xml:lang="fr">
		<title>3 - Wagtail</title>
		<link>https://edualc.be/spip.php?article97</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article97</guid>
		<dc:date>2026-10-25T14:26:40Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;nnn&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique10" rel="directory"&gt;Python&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;nnn&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>2 - Django</title>
		<link>https://edualc.be/spip.php?article96</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article96</guid>
		<dc:date>2026-10-25T14:26:38Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;nnnn&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique10" rel="directory"&gt;Python&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;nnnn&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>1 - Python</title>
		<link>https://edualc.be/spip.php?article95</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article95</guid>
		<dc:date>2026-10-25T14:26:34Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;nnnn&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique10" rel="directory"&gt;Python&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;nnnn&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>01 - Installation des outils</title>
		<link>https://edualc.be/spip.php?article94</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article94</guid>
		<dc:date>2026-10-25T14:18:31Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;Retour D&#233;veloppement d'un site en Python V&#233;rification de la pr&#233;sence de python Python doit &#234;tre install&#233; sur la machine de d&#233;veloppement. Sur une m&#234;me machine, plusieurs versions de pythons peuvent cohabiter sans probl&#232;me mais ++++ &lt;br class='autobr' /&gt;
Ouvrir une fen&#234;tre terminal Tester la pr&#233;sence de python &#8212; &gt; python3 &#8211; version Suivant la r&#233;ponse, installer si n&#233;cessaire la version voulue de python. &lt;br class='autobr' /&gt;
Installation de django Ouvrir une fen&#234;tre terminal Mettre &#224; jour l'utilitaire PIP : &#8212; &gt; python -m pip (&#8230;)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique10" rel="directory"&gt;Python&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;&lt;strong&gt;Retour&lt;/strong&gt; &lt;a href='https://edualc.be/spip.php?article93' class=&#034;spip_in&#034;&gt;D&#233;veloppement d'un site en Python&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;V&#233;rification de la pr&#233;sence de python&lt;/h3&gt;
&lt;p&gt;Python doit &#234;tre install&#233; sur la machine de d&#233;veloppement. Sur une m&#234;me machine, plusieurs versions de pythons peuvent cohabiter sans probl&#232;me mais ++++&lt;/p&gt;
&lt;p&gt;Ouvrir une fen&#234;tre terminal&lt;br class='autobr' /&gt;
Tester la pr&#233;sence de python
&lt;br /&gt;&#8212; &gt; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;python3 &#8211; version&lt;/code&gt;&lt;br class='autobr' /&gt;
Suivant la r&#233;ponse, installer si n&#233;cessaire la version voulue de python.&lt;/p&gt;
&lt;h3&gt;Installation de django&lt;/h3&gt;
&lt;p&gt;Ouvrir une fen&#234;tre terminal&lt;br class='autobr' /&gt;
Mettre &#224; jour l'utilitaire PIP :
&lt;br /&gt;&#8212; &gt; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;python -m pip install &#8212;upgrade pip&lt;/code&gt;&lt;br class='autobr' /&gt;
Installer django :
&lt;br /&gt;&#8212; &gt; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;python -m pip install django&lt;/code&gt;&lt;br class='autobr' /&gt;
Contr&#244;ler que Django est accessible par Python :
&lt;br /&gt;&#8212; &gt; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;python -m django &#8212;version&lt;/code&gt;&lt;br class='autobr' /&gt;
Une r&#233;ponse telle que 6.1.1 indique la bonne installation de python et de django.&lt;/p&gt;
&lt;h3&gt;Cr&#233;ation du projet&lt;/h3&gt;
&lt;p&gt;Le projet sera cr&#233;&#233; dans un r&#233;pertoire mysite cr&#233;&#233; lui-m&#234;me dans le r&#233;pertoire src&lt;br class='autobr' /&gt; &#8212; &gt; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;django-admin startproject mysite src&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;+++++++++++++++++++++++++++++++++++++++++++&lt;br class='autobr' /&gt;
+++++++++++++++++++++++++++++++++++++++++++&lt;/p&gt;
&lt;p&gt;1. Pr&#233;parer l'environnement de d&#233;veloppement&lt;/p&gt;
&lt;p&gt;Assurez-vous d'avoir Python 3 install&#233; sur votre machine.&lt;/p&gt;
&lt;p&gt;Cr&#233;ation d'un projet :&lt;/p&gt;
&lt;hr class=&#034;spip&#034; /&gt;
&lt;p&gt;&#8212; &gt; django-admin startproject mysite src
&lt;br /&gt;&#8212; &gt; cd src&lt;br class='autobr' /&gt;
### param&#232;tres : Modifier LANGUAGE_CODE = 'fr-fr' dans les param&#232;tres.
&lt;br /&gt;&#8212; &gt; python manage.py runserver
&lt;br /&gt;&#8212; &gt; [CTRL-c]&lt;/p&gt;
&lt;p&gt;Utilisons un mod&#232;le utilisateur personnalis&#233; :&lt;/p&gt;
&lt;hr class=&#034;spip&#034; /&gt;
&lt;p&gt;&lt;a href=&#034;https://openclassrooms.com/fr/courses/7192426-allez-plus-loin-avec-le-framework-django/7386368-personnalisez-le-modele-utilisateur&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;https://openclassrooms.com/fr/courses/7192426-allez-plus-loin-avec-le-framework-django/7386368-personnalisez-le-modele-utilisateur&lt;/a&gt;
&lt;br /&gt;&#8212; &gt; python manage.py startapp authentication&lt;br class='autobr' /&gt;
### param&#232;tres : Ajoutez l'applications aux INSTALLED_APPS dans les param&#232;tres.&lt;/p&gt;
&lt;p&gt;Cr&#233;ons une application blog :&lt;/p&gt;
&lt;hr class=&#034;spip&#034; /&gt;
&lt;p&gt;&#8212; &gt; python manage.py startapp blog&lt;br class='autobr' /&gt;
### param&#232;tres : Ajoutez l'applications aux INSTALLED_APPS dans les param&#232;tres.&lt;/p&gt;
&lt;p&gt;Etendre AbstractUser :&lt;/p&gt;
&lt;hr class=&#034;spip&#034; /&gt;
&lt;p&gt;Nous allons ajouter deux champs suppl&#233;mentaires :&lt;br class='autobr' /&gt; ImageField contenant une photo de profil,&lt;br class='autobr' /&gt; role , un CharField, qui diff&#233;renciera les diff&#233;rents types d'utilisateurs&lt;br class='autobr' /&gt; - administrateur&lt;br class='autobr' /&gt; - &#233;diteur&lt;br class='autobr' /&gt; - auteur&lt;br class='autobr' /&gt; - abonn&#233;&lt;br class='autobr' /&gt;
modifions authentication/models.py&lt;br class='autobr' /&gt; # authentication/models.py&lt;br class='autobr' /&gt; from django.contrib.auth.models import AbstractUser&lt;br class='autobr' /&gt; from django.db import models&lt;/p&gt;
&lt;p&gt; class User(AbstractUser) :&lt;br class='autobr' /&gt; &#034;&#034;&#034;&lt;br class='autobr' /&gt; On d&#233;finit des r&#244;les : cr&#233;ateur, abonn&#233;, lecteur, ...&lt;br class='autobr' /&gt; On les d&#233;finit comme des constantes.&lt;br class='autobr' /&gt; On peut ainsi tester si user.role == user.CREATOR, par ex.&lt;br class='autobr' /&gt; &#034;&#034;&#034;&lt;br class='autobr' /&gt; AUTEUR = 'AUTEUR'&lt;br class='autobr' /&gt; ABONNE = 'ABONNE'&lt;br class='autobr' /&gt; EDITEUR = 'EDITEUR'&lt;br class='autobr' /&gt; ADMINISTRATEUR = 'ADMINISTRATEUR'&lt;/p&gt;
&lt;p&gt; ROLE_CHOICES = (&lt;br class='autobr' /&gt; (AUTEUR, 'auteur'),&lt;br class='autobr' /&gt; (ABONNE, 'abonn&#233;'),&lt;br class='autobr' /&gt; (EDITEUR, '&#233;diteur'),&lt;br class='autobr' /&gt; (ADMINISTRATEUR, 'administrateur'),&lt;br class='autobr' /&gt; )&lt;/p&gt;
&lt;p&gt; profile_photo = models.ImageField(verbose_name='Photo de profil')&lt;br class='autobr' /&gt; role = models.CharField(max_length=30, choices=ROLE_CHOICES, verbose_name='R&#244;le')&lt;/p&gt;
&lt;p&gt;Django a besoin du package Pillow pour utiliser ImageField
&lt;br /&gt;&#8212; &gt; pip install Pillow
&lt;br /&gt;&#8212; &gt; pip freeze &gt; requirements.txt&lt;/p&gt;
&lt;p&gt;### param&#232;tres : Ajoutez AUTH_USER_MODEL = 'authentication.User' dans les param&#232;tres.&lt;/p&gt;
&lt;p&gt;G&#233;n&#233;rez et ex&#233;cutez les migrations initiales :&lt;/p&gt;
&lt;hr class=&#034;spip&#034; /&gt;
&lt;p&gt;&#8212; &gt; python manage.py makemigrations
&lt;br /&gt;&#8212; &gt; python manage.py migrate&lt;/p&gt;
&lt;p&gt;En r&#233;sum&#233;&lt;/p&gt;
&lt;hr class=&#034;spip&#034; /&gt;
&lt;p&gt; Django utilise le mod&#232;le User pour g&#233;rer l'authentification.&lt;br class='autobr' /&gt; C'est toujours une bonne id&#233;e d'utiliser un mod&#232;le User personnalis&#233;&lt;br class='autobr' /&gt; dans un projet, m&#234;me si nous n'avons pas besoin de fonctionnalit&#233;s&lt;br class='autobr' /&gt; suppl&#233;mentaires, car cela permet de faciliter grandement la personnalisation&lt;br class='autobr' /&gt; par la suite.&lt;/p&gt;
&lt;p&gt; Nous pouvons &#233;tendre AbstractUser pour enrichir le mod&#232;le User par d&#233;faut.&lt;/p&gt;
&lt;p&gt; Nous pouvons &#233;tendre AbstractBaseUser si nous voulons encore plus&lt;br class='autobr' /&gt; de flexibilit&#233;, et d&#233;finir tous les champs nous-m&#234;me.&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>0 - D&#233;veloppement d'un site en Python</title>
		<link>https://edualc.be/spip.php?article93</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article93</guid>
		<dc:date>2026-10-25T11:37:12Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;Objet &lt;br class='autobr' /&gt;
D&#233;velopper un site web en Python, un site web bas&#233; sur les outils Django et Wagtail &lt;br class='autobr' /&gt;
Python est un langage de programmation. &lt;br class='autobr' /&gt;
Django est ce qu'on appelle un framework, c-&#224;-d un ensemble de code servant de base pour cr&#233;er un site web. Django est bas&#233; sur python. &lt;br class='autobr' /&gt;
Wagtail est un syst&#232;me de gestion de contenu (CMS) construit enti&#232;rement sur Django, le framework web Python. &lt;br class='autobr' /&gt;
Cette triade (python &#8211; django &#8211; wagtail), est un outil puissant pour d&#233;velopper des pages web organis&#233;s en (&#8230;)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique10" rel="directory"&gt;Python&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;h3&gt;Objet&lt;/h3&gt;
&lt;p&gt;D&#233;velopper un site web en &lt;strong&gt;Python&lt;span class=&#034;spip_note_ref&#034;&gt; [&lt;a href=&#034;#nb1&#034; class=&#034;spip_note&#034; rel=&#034;appendix&#034; title=&#034;Python&#034; id=&#034;nh1&#034;&gt;1&lt;/a&gt;]&lt;/span&gt;&lt;/strong&gt;, un site web bas&#233; sur les outils &lt;strong&gt;Django&lt;span class=&#034;spip_note_ref&#034;&gt; [&lt;a href=&#034;#nb2&#034; class=&#034;spip_note&#034; rel=&#034;appendix&#034; title=&#034;Django&#034; id=&#034;nh2&#034;&gt;2&lt;/a&gt;]&lt;/span&gt;&lt;/strong&gt; et &lt;strong&gt;Wagtail&lt;span class=&#034;spip_note_ref&#034;&gt; [&lt;a href=&#034;#nb3&#034; class=&#034;spip_note&#034; rel=&#034;appendix&#034; title=&#034;Wagtail&#034; id=&#034;nh3&#034;&gt;3&lt;/a&gt;]&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Python est un langage de programmation.&lt;/p&gt;
&lt;p&gt;Django est ce qu'on appelle un framework, c-&#224;-d un ensemble de code servant de base pour cr&#233;er un site web. Django est bas&#233; sur python.&lt;/p&gt;
&lt;p&gt;Wagtail est un syst&#232;me de gestion de contenu (CMS) construit enti&#232;rement sur Django, le framework web Python.&lt;/p&gt;
&lt;p&gt;Cette triade (python &#8211; django &#8211; wagtail), est un outil puissant pour d&#233;velopper des pages web organis&#233;s en sites, projets et applications.&lt;/p&gt;
&lt;p&gt;Dans ce projet, plusieurs applications :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Utilisateurs&lt;/i&gt;&lt;/strong&gt; : une application de gestion des utilisateurs et de leurs permissions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Blog&lt;/i&gt;&lt;/strong&gt; : une application de publication de notes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Photos&lt;/i&gt;&lt;/strong&gt; : une application de diaporama&lt;/p&gt;
&lt;p&gt;D'autres applications viendront se joindre aux premi&#232;res, et toutes exploiteront la premi&#232;re application, &lt;strong&gt;&lt;i&gt;Utilisateurs&lt;/i&gt;&lt;/strong&gt;, pour d&#233;finir les autorisations d'acc&#232;s ad&#233;quates aux donn&#233;es (autorisations de lecture, cr&#233;ation, modifications, etc).&lt;/p&gt;
&lt;h3&gt;Table des mati&#232;res&lt;/h3&gt;&lt;ol class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;a href='https://edualc.be/spip.php?article94' class=&#034;spip_in&#034;&gt;Installation des outils&lt;/a&gt;&lt;/li&gt;&lt;li&gt; Installation de l'ossature du projet&lt;/li&gt;&lt;li&gt; Installation de l'application &lt;i&gt; &lt;strong&gt;Utilisateurs&lt;/strong&gt; &lt;/i&gt;&lt;/li&gt;&lt;li&gt; Installation des autres applications&lt;/li&gt;&lt;li&gt; &lt;i&gt; &lt;strong&gt;Blog&lt;/strong&gt; &lt;/i&gt;&lt;/li&gt;&lt;li&gt; &lt;i&gt; &lt;strong&gt;Photos&lt;/strong&gt; &lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
		&lt;hr /&gt;
		&lt;div class='rss_notes'&gt;&lt;div id=&#034;nb1&#034;&gt;
&lt;p&gt;&lt;span class=&#034;spip_note_ref&#034;&gt;[&lt;a href=&#034;#nh1&#034; class=&#034;spip_note&#034; title=&#034;Notes 1&#034; rev=&#034;appendix&#034;&gt;1&lt;/a&gt;] &lt;/span&gt;Python&lt;/p&gt;
&lt;/div&gt;&lt;div id=&#034;nb2&#034;&gt;
&lt;p&gt;&lt;span class=&#034;spip_note_ref&#034;&gt;[&lt;a href=&#034;#nh2&#034; class=&#034;spip_note&#034; title=&#034;Notes 2&#034; rev=&#034;appendix&#034;&gt;2&lt;/a&gt;] &lt;/span&gt;Django&lt;/p&gt;
&lt;/div&gt;&lt;div id=&#034;nb3&#034;&gt;
&lt;p&gt;&lt;span class=&#034;spip_note_ref&#034;&gt;[&lt;a href=&#034;#nh3&#034; class=&#034;spip_note&#034; title=&#034;Notes 3&#034; rev=&#034;appendix&#034;&gt;3&lt;/a&gt;] &lt;/span&gt;Wagtail&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Django -01- gestion des utilisateurs</title>
		<link>https://edualc.be/spip.php?article89</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article89</guid>
		<dc:date>2026-09-01T17:06:13Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;https://contentgardeningstudio.com/python/gerer-des-comptes-utilisateurs-et-profils-personnalises-pour-votre-site-django/ &lt;br class='autobr' /&gt;
https://openclassrooms.com/fr/courses/7192426-allez-plus-loin-avec-le-framework-django/7386368-personnalisez-le-modele-utilisateur &lt;br class='autobr' /&gt;
Notre ambition est de publier notre site. Mais pour qui et pour y faire quoi ? Nous voulons en rendre certaines parties publiques et d'autres restreintes &#224; des personnes choisies. Nous pouvons aussi donner des droits pour certaines parties (&#8230;)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique15" rel="directory"&gt;Django&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;&lt;a href=&#034;https://contentgardeningstudio.com/python/gerer-des-comptes-utilisateurs-et-profils-personnalises-pour-votre-site-django/&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;https://contentgardeningstudio.com/python/gerer-des-comptes-utilisateurs-et-profils-personnalises-pour-votre-site-django/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#034;https://openclassrooms.com/fr/courses/7192426-allez-plus-loin-avec-le-framework-django/7386368-personnalisez-le-modele-utilisateur&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;https://openclassrooms.com/fr/courses/7192426-allez-plus-loin-avec-le-framework-django/7386368-personnalisez-le-modele-utilisateur&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notre ambition est de publier notre site. Mais pour qui et pour y faire quoi ? Nous voulons en rendre certaines parties publiques et d'autres restreintes &#224; des personnes choisies. Nous pouvons aussi donner des droits pour certaines parties du site, &#224; des personnes autoris&#233;es, tels que cr&#233;er ou modifier tel ou tel article, telle ou telle donn&#233;e.&lt;/p&gt;
&lt;p&gt;Apr&#232;s avoir cr&#233;&#233; un projet lors de l'installation de Django, nous allons construire une application d'authentification &#224; partir de ces premiers principes : les utilisateurs pourront se connecter et se d&#233;connecter de notre application web.&lt;/p&gt;
&lt;p&gt;Django fournit un mod&#232;le d'utilisateurs (&lt;strong&gt;User&lt;/strong&gt;). Ce mod&#232;le poss&#232;de de nombreuses m&#233;thodes et fonctionnalit&#233;s sp&#233;ciales, en particulier en ce qui concerne l'authentification et les permissions, qui lui permettent de s'int&#233;grer automatiquement au framework Django.&lt;/p&gt;
&lt;h2 class=&#034;spip&#034;&gt;La liste des champs du mod&#232;le User&#182;&lt;/h2&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;strong&gt;username&lt;/strong&gt;&#182; Obligatoire. Au maximum 150 caract&#232;res. Les noms d'utilisateur peuvent contenir des caract&#232;res alphanum&#233;riques (_, @, +, . et -).&lt;/li&gt;&lt;li&gt; &lt;strong&gt;first_name&lt;/strong&gt;&#182; Facultatif (blank=True). 150 caract&#232;res ou moins.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;last_name&lt;/strong&gt;&#182; Facultatif (blank=True). 150 caract&#232;res ou moins.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;email&lt;/strong&gt;&#182; Facultatif (blank=True). Adresse &#233;lectronique.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;password&lt;/strong&gt;&#182; Obligatoire. Une empreinte avec m&#233;tadonn&#233;es du mot de passe (Django ne stocke pas le mot de passe en clair). La longueur des mots de passe r&#233;els n'est pas limit&#233;e, ni les caract&#232;res qu'ils contiennent. Les m&#233;tadonn&#233;es de ce champ peuvent aussi marquer le mot de passe comme inutilisable. &lt;a href=&#034;https://docs.djangoproject.com/fr/6.1/topics/auth/passwords/&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;Voir la documentation sur les mots de passe&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;groups&lt;/strong&gt;&#182; Une relation plusieurs-&#224;-plusieurs vers Group.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;user_permissions&lt;/strong&gt;&#182; Une relation plusieurs-&#224;-plusieurs vers Permission.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;is_staff&lt;/strong&gt;&#182; Valeur bool&#233;enne. Permet &#224; cet utilisateur d'acc&#233;der au site d'administration.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;is_active&lt;/strong&gt;&#182; Valeur bool&#233;enne. Marque ce compte utilisateur comme actif. Nous recommandons de d&#233;finir ce drapeau &#224; False au lieu de supprimer le compte. Ainsi, si vos applications comportent des cl&#233;s &#233;trang&#232;res vers des utilisateurs, les cl&#233;s &#233;trang&#232;res ne seront pas cass&#233;es.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&#034;avertissement&#034;&gt;Ceci ne d&#233;termine pas forc&#233;ment si l'utilisateur peut se connecter ou non. Les moteurs d'authentification ne sont pas oblig&#233;s de v&#233;rifier le drapeau is_active, mais le moteur par d&#233;faut (ModelBackend) et le moteur RemoteUserBackend le font. Vous pouvez utiliser AllowAllUsersModelBackend ou AllowAllUsersRemoteUserBackend si vous voulez autoriser les utilisateurs inactifs &#224; se connecter. Dans ce cas, vous devrez aussi adapter le formulaire AuthenticationForm utilis&#233; par la vue LoginView car il rejette les utilisateurs inactifs. Soyez conscient que les m&#233;thodes de contr&#244;le des permissions telles que has_perm() ainsi que l'authentification dans le site d'administration de Django renvoient toutes False pour les utilisateurs inactifs.&lt;/div&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;strong&gt;is_superuser&lt;/strong&gt;&#182; Valeur bool&#233;enne. Consid&#232;re cet utilisateur comme ayant toutes les permissions sans devoir lui en attribuer aucune en particulier.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;last_login&lt;/strong&gt;&#182; Horodatage de la derni&#232;re connexion de l'utilisateur.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;date_joined&lt;/strong&gt;&#182; L'horodatage de la cr&#233;ation du compte.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Mais ce mod&#232;le ne r&#233;pond peut-&#234;tre pas &#224; tous nos besoins. Par exemple, nous pourrions vouloir ajouter des champs suppl&#233;mentaires comme une photo de profil ou des liens vers des r&#233;seaux sociaux. Dans ces cas, il est recommand&#233; de cr&#233;er un mod&#232;le d'utilisateur personnalis&#233;.&lt;/p&gt;
&lt;h2 class=&#034;spip&#034;&gt;Utilisons un mod&#232;le utilisateur personnalis&#233;&lt;/h2&gt;&lt;div class=&#034;important&#034;&gt;Nous conseillons de toujours impl&#233;menter un mod&#232;le User personnalis&#233; dans notre projet. Et ce, m&#234;me s'il est identique au mod&#232;le par d&#233;faut !&lt;/div&gt;
&lt;p&gt;Car il est difficile et compliqu&#233; de migrer vers un mod&#232;le User personnalis&#233; apr&#232;s la configuration de notre site Django et l'ex&#233;cution des migrations initiales.&lt;/p&gt;
&lt;p&gt;Afin de cr&#233;er un mod&#232;le User personnalis&#233;, Django fournit deux classes de base que nous pouvons &#233;tendre pour r&#233;pondre &#224; nos besoins sp&#233;cifiques :&lt;/p&gt;
&lt;h2 class=&#034;spip&#034;&gt;AbstractUser&lt;/h2&gt;
&lt;p&gt;La classe AbstractUser contient tous les champs et les m&#233;thodes du User par d&#233;faut.&lt;/p&gt;
&lt;p&gt;Si les fonctionnalit&#233;s de la classe User par d&#233;faut r&#233;pondent &#224; nos besoins &#224; elles seules, alors il est vraiment facile de l'utiliser comme mod&#232;le User personnalis&#233; :&lt;/p&gt;
&lt;p&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;from django.contrib.auth.models import AbstractUser class User(AbstractUser): pass&lt;/code&gt;&lt;br class='autobr' /&gt;
Ceci fournit tous les champs et fonctionnalit&#233;s du mod&#232;le User par d&#233;faut, avec la souplesse suppl&#233;mentaire de pouvoir y ajouter des champs et des m&#233;thodes par la suite.&lt;/p&gt;
&lt;p&gt;Mais que se passe-t-il si nous ne voulons pas utiliser tous les champs fournis dans la classe User par d&#233;faut ? Dans ce cas, nous allons plut&#244;t &#233;tendre la classe AbstractBaseUser .&lt;/p&gt;
&lt;h2 class=&#034;spip&#034;&gt;AbstractBaseUser&lt;/h2&gt;
&lt;p&gt;La classe AbstractBaseUser ne contient aucun champ, except&#233; password (mot de passe). Elle poss&#232;de aussi une suite de m&#233;thodes pour g&#233;rer l'authentification (tout comme AbstractUser).&lt;/p&gt;
&lt;p&gt;Lorsque nous &#233;tendeons AbstractBaseUser, nous devons sp&#233;cifier tous les champs que nous voulons inclure (sauf password ). Il faut aussi un peu de configuration suppl&#233;mentaire pour qu'elle s'int&#232;gre bien au syst&#232;me d'authentification de Django.&lt;/p&gt;
&lt;p&gt;Les configurations cl&#233;s &#224; impl&#233;menter avec le mod&#232;le AbstractBaseUser sont les suivantes :&lt;/p&gt;
&lt;p&gt; USERNAME_FIELD &#8212; indique le nom du champ devant &#234;tre utilis&#233; comme identifiant de connexion.&lt;/p&gt;
&lt;p&gt; EMAIL_FIELD &#8212; indique le nom du champ contenant l'adresse e-mail principale d'un utilisateur ('email' par d&#233;faut).&lt;/p&gt;
&lt;p&gt; REQUIRED_FIELDS &#8212; liste des champs &#224; sp&#233;cifier obligatoirement lors de l'utilisation de la commande python manage.py createsuperuser.&lt;/p&gt;
&lt;p&gt; is_active &#8212; vaut True par d&#233;faut dans AbstractBaseUser, mais nous pouvons ajouter notre propre champ si nous voulons g&#233;rer les utilisateurs actifs et inactifs.&lt;/p&gt;
&lt;p&gt;il faut installer Pillow&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;python -m pip install Pillow&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&gt;&gt; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;python manage.py migrate&lt;/code&gt;&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>D&#233;buts</title>
		<link>https://edualc.be/spip.php?article88</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article88</guid>
		<dc:date>2026-09-01T16:24:00Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;Initiation &#224; Affinity (Photo)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique19" rel="directory"&gt;Affinity&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;&lt;a href=&#034;https://ch22.fr/numeric/affinity_photo/contenu.html&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;Initiation &#224; Affinity (Photo)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>SQLAlchemy - Op&#233;rations CRUD avec les Sessions SQLAlchemy</title>
		<link>https://edualc.be/spip.php?article87</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article87</guid>
		<dc:date>2026-08-22T14:37:45Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;La Session est le composant central de l'ORM SQLAlchemy. Elle impl&#233;mente le pattern Unit of Work : les modifications sont accumul&#233;es en m&#233;moire puis envoy&#233;es &#224; la base de donn&#233;es en une seule transaction lors du commit(). Cette approche garantit la coh&#233;rence des donn&#233;es et optimise les performances en regroupant les op&#233;rations. ``` &lt;br class='autobr' /&gt;
from sqlalchemy.orm import sessionmaker &lt;br class='autobr' /&gt;
# Cr&#233;er une factory de sessions SessionLocal = sessionmaker(bind=engine_dev) &lt;br class='autobr' /&gt;
# === CREATE : Ajouter des donn&#233;es === (&#8230;)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique17" rel="directory"&gt;SQLAlchemy&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;La Session est le composant central de l'ORM SQLAlchemy. Elle impl&#233;mente le pattern Unit of Work : les modifications sont accumul&#233;es en m&#233;moire puis envoy&#233;es &#224; la base de donn&#233;es en une seule transaction lors du commit(). Cette approche garantit la coh&#233;rence des donn&#233;es et optimise les performances en regroupant les op&#233;rations.&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre class='spip_code spip_code_block' dir='ltr' style='text-align:left;'&gt;&lt;code&gt; from sqlalchemy.orm import sessionmaker # Cr&#233;er une factory de sessions SessionLocal = sessionmaker(bind=engine_dev) # === CREATE : Ajouter des donn&#233;es === with SessionLocal() as session: # Cr&#233;er un utilisateur avec des articles alice = Utilisateur( nom=&#034;Alice Dupont&#034;, email=&#034;alice@example.com&#034;, articles=[ Article(titre=&#034;Introduction &#224; Python&#034;, contenu=&#034;Python est un langage...&#034;), Article(titre=&#034;SQLAlchemy pour d&#233;butants&#034;, contenu=&#034;SQLAlchemy est un ORM...&#034;) ] ) session.add(alice) session.commit() print(f&#034;Cr&#233;&#233; : {alice}&#034;) print(f&#034;Articles : {alice.articles}&#034;) # Sortie : # Cr&#233;&#233; : Utilisateur(id=1, nom='Alice Dupont') # Articles : [Article(id=1, titre='Introduction &#224; Python'), Article(id=2, titre='SQLAlchemy pour d&#233;butants')] # === READ : Lire des donn&#233;es === with SessionLocal() as session: # Par cl&#233; primaire user = session.get(Utilisateur, 1) print(f&#034;Trouv&#233; : {user}&#034;) # Avec filtre from sqlalchemy import select stmt = select(Utilisateur).where(Utilisateur.email == &#034;alice@example.com&#034;) user = session.execute(stmt).scalar_one() print(f&#034;Par email : {user}&#034;) # Sortie : # Trouv&#233; : Utilisateur(id=1, nom='Alice Dupont') # Par email : Utilisateur(id=1, nom='Alice Dupont') # === UPDATE : Mettre &#224; jour === with SessionLocal() as session: user = session.get(Utilisateur, 1) user.nom = &#034;Alice Martin&#034; session.commit() print(f&#034;Mis &#224; jour : {user}&#034;) # Sortie : Mis &#224; jour : Utilisateur(id=1, nom='Alice Martin') # === DELETE : Supprimer === with SessionLocal() as session: user = session.get(Utilisateur, 1) session.delete(user) # Supprime aussi les articles (cascade) session.commit() print(&#034;Utilisateur et articles supprim&#233;s&#034;) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;L'utilisation du context manager with SessionLocal() as session garantit que la session est correctement ferm&#233;e, m&#234;me en cas d'exception. C'est une bonne pratique essentielle qui &#233;vite les fuites de connexions. En cas d'erreur pendant le commit, la session effectue automatiquement un rollback.&lt;/p&gt;
&lt;p&gt;Remarquez l'utilisation de select() au lieu de session.query(). La m&#233;thode session.query() est l'ancienne API 1.x, toujours fonctionnelle mais consid&#233;r&#233;e comme legacy. Le style 2.0 avec select() est plus explicite, plus composable et compatible avec le mode async. Adoptez-le syst&#233;matiquement pour tout nouveau code.&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>SQLAlchemy - D&#233;finir les Mod&#232;les avec le Nouveau Style D&#233;claratif 2.0</title>
		<link>https://edualc.be/spip.php?article86</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article86</guid>
		<dc:date>2026-08-21T14:30:13Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;tutoriel sqlalchemy Pr&#233;c&#233;dent &lt;br class='autobr' /&gt;
SQLAlchemy 2 introduit un nouveau style d&#233;claratif bas&#233; sur DeclarativeBase et Mapped. Ce style offre un typage natif complet compatible avec mypy et Pyright &lt;br class='autobr' /&gt;
Les annotations de type sont d&#233;sormais utilis&#233;es pour d&#233;finir les colonnes, ce qui rend le code plus lisible et v&#233;rifiable statiquement. &lt;br class='autobr' /&gt;
``` &lt;br class='autobr' /&gt;
from datetime import datetime from typing import Optional, List from sqlalchemy import String, ForeignKey, func from sqlalchemy.orm import ( (&#8230;)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique17" rel="directory"&gt;SQLAlchemy&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;&lt;a href=&#034;https://tech-insider.org/fr/tutoriel-sqlalchemy-python-orm-crud-2026/&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;tutoriel sqlalchemy&lt;/a&gt;&lt;br class='autobr' /&gt;
&lt;a href='https://edualc.be/spip.php?article85' class=&#034;spip_in&#034;&gt;Pr&#233;c&#233;dent&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SQLAlchemy 2 introduit un nouveau style d&#233;claratif bas&#233; sur D&lt;i&gt;eclarativeBase&lt;/i&gt; et &lt;i&gt;Mapped&lt;/i&gt;. Ce style offre un typage natif complet compatible avec mypy et Pyright&lt;/p&gt;
&lt;p&gt;Les annotations de type sont d&#233;sormais utilis&#233;es pour d&#233;finir les colonnes, ce qui rend le code plus lisible et v&#233;rifiable statiquement.&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre class='spip_code spip_code_block' dir='ltr' style='text-align:left;'&gt;&lt;code&gt; from datetime import datetime from typing import Optional, List from sqlalchemy import String, ForeignKey, func from sqlalchemy.orm import ( DeclarativeBase, Mapped, mapped_column, relationship, Session ) # Classe de base pour tous les mod&#232;les class Base(DeclarativeBase): pass # Mod&#232;le Utilisateur class Utilisateur(Base): __tablename__ = &#034;utilisateurs&#034; id: Mapped[int] = mapped_column(primary_key=True) nom: Mapped[str] = mapped_column(String(100)) email: Mapped[str] = mapped_column(String(255), unique=True, index=True) actif: Mapped[bool] = mapped_column(default=True) date_creation: Mapped[datetime] = mapped_column( server_default=func.now() ) # Relation one-to-many vers les articles articles: Mapped[List[&#034;Article&#034;]] = relationship( back_populates=&#034;auteur&#034;, cascade=&#034;all, delete-orphan&#034; ) def __repr__(self) -&gt; str: return f&#034;Utilisateur(id={self.id}, nom='{self.nom}')&#034; # Mod&#232;le Article class Article(Base): __tablename__ = &#034;articles&#034; id: Mapped[int] = mapped_column(primary_key=True) titre: Mapped[str] = mapped_column(String(200)) contenu: Mapped[str] = mapped_column(String(5000)) publie: Mapped[bool] = mapped_column(default=False) auteur_id: Mapped[int] = mapped_column(ForeignKey(&#034;utilisateurs.id&#034;)) date_publication: Mapped[Optional[datetime]] = mapped_column( nullable=True ) # Relation many-to-one vers l'utilisateur auteur: Mapped[&#034;Utilisateur&#034;] = relationship( back_populates=&#034;articles&#034; ) def __repr__(self) -&gt; str: return f&#034;Article(id={self.id}, titre='{self.titre}')&#034; # Cr&#233;er toutes les tables Base.metadata.create_all(engine_dev) print(&#034;Tables cr&#233;&#233;es avec succ&#232;s !&#034;) # Sortie : # CREATE TABLE utilisateurs (...) # CREATE TABLE articles (...) # Tables cr&#233;&#233;es avec succ&#232;s ! &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notez l'utilisation de Mapped[str] au lieu du classique Column(String). Ce nouveau style d&#233;claratif 2.0 apporte plusieurs avantages : autocompl&#233;tion dans les IDE, v&#233;rification de types statique, et une syntaxe plus concise. Le type Python Optional[datetime] se traduit automatiquement en colonne nullable, tandis que Mapped[str] cr&#233;e une colonne NOT NULL par d&#233;faut.&lt;/p&gt;
&lt;p&gt;La directive cascade=&#034;all, delete-orphan&#034; sur la relation articles signifie que la suppression d'un utilisateur supprime automatiquement tous ses articles. C'est le comportement souhait&#233; dans la plupart des cas, mais attention en production : v&#233;rifiez toujours que les cascades correspondent &#224; votre logique m&#233;tier.&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>SQLAlchemy - Cr&#233;er le Moteur et la Connexion &#224; la Base de Donn&#233;es</title>
		<link>https://edualc.be/spip.php?article85</link>
		<guid isPermaLink="true">https://edualc.be/spip.php?article85</guid>
		<dc:date>2026-08-16T15:19:07Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>edualc</dc:creator>







		<description>
&lt;p&gt;tutoriel sqlalchemy Pr&#233;c&#233;dant &lt;br class='autobr' /&gt;
Engine &lt;br class='autobr' /&gt;
Le point de d&#233;part de toute application SQLAlchemy est un objet appel&#233; &#171; Engine &#187;. C'est le point d'entr&#233;e de toute interaction avec la base de donn&#233;es dans SQLAlchemy. Il g&#232;re le pool de connexions, le dialecte SQL sp&#233;cifique au SGBD, et la cr&#233;ation des connexions. Il est g&#233;n&#233;ralement cr&#233;&#233; une seule fois pour un serveur de base de donn&#233;es donn&#233;. Il est configur&#233; &#224; l'aide d'une cha&#238;ne d'URL d&#233;crivant la mani&#232;re de se connecter &#224; l'h&#244;te ou au (&#8230;)&lt;/p&gt;


-
&lt;a href="https://edualc.be/spip.php?rubrique17" rel="directory"&gt;SQLAlchemy&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;&lt;a href=&#034;https://tech-insider.org/fr/tutoriel-sqlalchemy-python-orm-crud-2026/&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;tutoriel sqlalchemy&lt;/a&gt;&lt;br class='autobr' /&gt;
&lt;strong&gt;&lt;a href='https://edualc.be/spip.php?article84' class=&#034;spip_in&#034;&gt;Pr&#233;c&#233;dant&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 class=&#034;spip&#034;&gt;Engine&lt;/h2&gt;
&lt;p&gt;Le point de d&#233;part de toute application SQLAlchemy est un objet appel&#233; &#171; &lt;strong&gt;Engine&lt;/strong&gt; &#187;.&lt;/p&gt;
&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; C'est le point d'entr&#233;e de toute interaction avec la base de donn&#233;es dans SQLAlchemy.&lt;/li&gt;&lt;li&gt; Il g&#232;re le pool de connexions, le dialecte SQL sp&#233;cifique au SGBD, et la cr&#233;ation des connexions.&lt;/li&gt;&lt;li&gt; Il est g&#233;n&#233;ralement cr&#233;&#233; une seule fois pour un serveur de base de donn&#233;es donn&#233;.&lt;/li&gt;&lt;li&gt; Il est configur&#233; &#224; l'aide d'une cha&#238;ne d'URL d&#233;crivant la mani&#232;re de se connecter &#224; l'h&#244;te ou au syst&#232;me backend de la base de donn&#233;es.&lt;/li&gt;&lt;li&gt; L'objet &lt;strong&gt;Engine&lt;/strong&gt; est cr&#233;&#233; &#224; l'aide de la fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;create_engine()&lt;/code&gt;
&lt;div class='spip_document_18 spip_document spip_documents spip_document_image spip_documents_center spip_document_center'&gt;
&lt;figure class=&#034;spip_doc_inner&#034;&gt; &lt;img src='https://edualc.be/IMG/png/sqla_engine_arch.png?1787305610' width='500' height='135' alt='' /&gt;
&lt;/figure&gt;
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&#034;info-escal&#034;&gt;
rappel : La syntaxe g&#233;n&#233;rale des URL est la suivante : protocole:partie_sp&#233;cifique
&lt;p&gt;Les URL commencent par un protocole Internet ou autre suivi du caract&#232;re deux-points ; la partie_sp&#233;cifique est souvent constitu&#233;e d'un nom de domaine et / ou d'un chemin d'acc&#232;s.&lt;br class='autobr' /&gt;
exemples :&lt;/p&gt;
&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;a href=&#034;https://www.lesoir.be/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;https://www.lesoir.be/&lt;/a&gt;&lt;/li&gt;&lt;li&gt; sqlite+pysqlite :////mondisque/mesdonn&#233;es/mabasededonn&#233;es.db
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&#034;spip&#034;&gt;SQLite&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Protocole&lt;/strong&gt;&lt;br class='autobr' /&gt;
SQLite se connecte &#224; des bases de donn&#233;es bas&#233;es sur des fichiers, en utilisant par d&#233;faut le module int&#233;gr&#233; de Python &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sqlite3&lt;/code&gt;, sp&#233;cifi&#233; par &lt;strong&gt;sqlite&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;La DBAPI Python est un pilote tiers qu'utilise SQLAlchemy pour interagir avec une base de donn&#233;es sp&#233;cifique. Ici, nous utilisons le nom &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;pysqlite&lt;/code&gt; qui, dans les usages actuels de Python, d&#233;signe l'interface de la biblioth&#232;que standard &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sqlite3&lt;/code&gt; pour SQLite. Si ce param&#232;tre est omis, SQLAlchemy utilisera une DBAPI par d&#233;faut adapt&#233;e &#224; la base de donn&#233;es choisie.&lt;/p&gt;
&lt;p&gt;Comme SQLite se connecte &#224; des fichiers locaux, l'URL est constitu&#233;e comme suit :&lt;br class='autobr' /&gt;
protocole -&gt; sqlite+pysqlite&lt;br class='autobr' /&gt;
partie_sp&#233;cifique -&gt; la partie &#171; file &#187; de l'URL correspond au nom du fichier de la base de donn&#233;es.&lt;/p&gt;
&lt;p&gt;Pour un &lt;strong&gt;chemin d'acc&#232;s relatif&lt;/strong&gt;, cela n&#233;cessite trois barres obliques :&lt;br class='autobr' /&gt;
# sqlite :///&#171; path &#187;&lt;br class='autobr' /&gt;
# o&#249; &#171; path &#187; est relatif&lt;br class='autobr' /&gt;
exemple : &lt;i&gt;engine = create_engine(&#034;sqlite+pysqlite :///foo.db&#034;)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Et pour un c&lt;strong&gt;hemin de fichier absolu&lt;/strong&gt;, les trois barres obliques sont suivies du chemin absolu :&lt;/p&gt;
&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; # &lt;strong&gt;Unix/Mac&lt;/strong&gt; - 4 barres obliques initiales au total&lt;br class='manualbr' /&gt;&lt;i&gt;engine = create_engine(&#034;sqlite+pysqlite :////absolute/path/to/foo.db&#034;)&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; # &lt;strong&gt;Windows&lt;/strong&gt; - 3 barres obliques initiales&lt;br class='manualbr' /&gt;&lt;i&gt;engine = create_engine(&#034;sqlite+pysqlite :///C :\path\to\foo.db&#034;)&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; # &lt;strong&gt;Windows alternative using raw string&lt;/strong&gt;&lt;br class='manualbr' /&gt;&lt;i&gt;engine = create_engine(r&#034;sqlite+pysqlite :///C :\path\to\foo.db&#034;)&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Pour utiliser une base de donn&#233;es SQLite en &lt;strong&gt;m&#233;moire&lt;/strong&gt; (:memory :), sp&#233;cifiez une URL vide :&lt;br class='autobr' /&gt;
&lt;i&gt;engine = create_engine(&#034;sqlite+pysqlite ://&#034;)&lt;/i&gt;&lt;/p&gt;
&lt;div class=&#034;avertissement&#034;&gt;
&lt;strong&gt;Lazy Connecting&lt;/strong&gt;
&lt;p&gt;L'objet &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;Engine&lt;/code&gt;, tel qu'il est renvoy&#233; par &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;create_engine()&lt;/code&gt;, n'a pas encore tent&#233; de se connecter &#224; la base de donn&#233;es ; cette connexion ne s'&#233;tablit que lorsqu'il est sollicit&#233; pour la premi&#232;re fois pour effectuer une op&#233;ration sur la base. Il s'agit d'un mod&#232;le de conception logiciel connu sous le nom d'initialisation paresseuse (*lazy initialization*).&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Plus de pr&#233;cisions sur la connexion &#224; SQLite sur SQLite.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;i&gt;PostgreSQL&lt;/i&gt; &lt;/strong&gt;&lt;br class='autobr' /&gt;
Cr&#233;ons un moteur pour PostgreSQL (production).&lt;/p&gt;
&lt;p&gt;from sqlalchemy import create_engine, text&lt;/p&gt;
&lt;p&gt;# PostgreSQL pour la production&lt;br class='autobr' /&gt;
engine = create_engine(&lt;br class='autobr' /&gt; &#034;postgresql+psycopg2 ://user:password@localhost:5432/mabase&#034;,&lt;br class='autobr' /&gt; pool_size=10, # Connexions maintenues en pool&lt;br class='autobr' /&gt; max_overflow=20, # Connexions suppl&#233;mentaires autoris&#233;es&lt;br class='autobr' /&gt; pool_recycle=3600, # Recyclage des connexions apr&#232;s 1h&lt;br class='autobr' /&gt; pool_pre_ping=True, # V&#233;rification de connexion avant utilisation&lt;br class='autobr' /&gt; echo=False # D&#233;sactiv&#233; en production&lt;br class='autobr' /&gt;
)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;i&gt;Tester la connexion&lt;/i&gt; &lt;/strong&gt;&lt;br class='autobr' /&gt;
with engine.connect() as conn :&lt;br class='autobr' /&gt; result = conn.execute(text(&#034;SELECT 1&#034;))&lt;br class='autobr' /&gt; print(f&#034;Connexion r&#233;ussie : &lt;i&gt;result.scalar()&lt;/i&gt;&#034;)&lt;br class='autobr' /&gt;
# Sortie : Connexion r&#233;ussie : 1&lt;/p&gt;
&lt;div class=&#034;aide&#034;&gt;Le param&#232;tre echo=True est indispensable pendant le d&#233;veloppement : il affiche chaque requ&#234;te SQL g&#233;n&#233;r&#233;e par SQLAlchemy dans la console. D&#233;sactivez-le en production pour &#233;viter de polluer les logs. Le pool_pre_ping=True est crucial en production car il v&#233;rifie que chaque connexion est encore valide avant de l'utiliser, &#233;vitant les erreurs &#8220;connection closed&#8221; apr&#232;s un red&#233;marrage de la base de donn&#233;es.
&lt;p&gt;La cha&#238;ne de connexion suit le format dialect+driver ://user:password@host:port/database. Pour PostgreSQL, le driver par d&#233;faut est psycopg2. Pour MySQL, utilisez mysql+pymysql ://. Pour SQLite, la syntaxe sqlite :///fichier.db cr&#233;e un fichier local, tandis que sqlite :///:memory : cr&#233;e une base en m&#233;moire (id&#233;ale pour les tests unitaires).&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='https://edualc.be/spip.php?article86' class=&#034;spip_in&#034;&gt;D&#233;finir les Mod&#232;les avec le Nouveau Style D&#233;claratif 2.0&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>



</channel>

</rss>