HTTP Avxhome - Se Blogs ALGEROIS PDF
HTTP Avxhome - Se Blogs ALGEROIS PDF
HTTP Avxhome - Se Blogs ALGEROIS PDF
Membre de l'Académie Royale de Belgique, Hugues Bersini enseigne l'informatique et la programmation aux facultés poly-
technique et Solvay de l'Université Libre de Bruxelles, dont il dirige le laboratoire d'lntelligence Artificielle. li est l'auteur de
très nombreuses publications (systèmes complexes, génie logiciel, sciences cognitives et bioinformatique).
Pierre Alexis est titulaire d'une licence en informatique et travaille au service informatique de la plus grande banque pri-
vée belge. Intéressé depuis toujours par l'enseignement et la vulgarisation informatique, il assiste Hugues Bersini à
l'Université libre de Bruxelles et dispense un cours de Django/Python à destination d'étudiants en ingénierie commerciale.
Enfin un ouvrage pour étudiants détaillant tous les principes de la programmation web moderne, ovec l'un des frameworks de développement web
les plus ambitieux : Diango, basé sur le langage Python !
Un manuel autonome reprenant tous les fondements de la programmation web, au fil d'une étude de cas inspirée de Facebook
Abondamment illustré d'exemples inspirés de Facebook et rappelant les bonnes pratiques du domaine (modèle MVC, diagrammes UML, patterns),
voici un livre de cours magistral et moderne sur Io programmation web dynamique, que tous les enseignants en informatique peuvent utiliser.
Complet et autonome, il pose solidement les fondamentaux de la conception web, avec ou sans framework : HTML5/CSS3, dynamisme alimenté
par bases relationnelles SQL, sessions, JavaScript et Ajax, sons oublier de fournir au lecteur d'essentiels rappels en programmation objet, voire
de montrer ... ce qu'il ne faut pas faire en CGI !
Le langage Python et le framework Django sont introduits en douceur, et l'utilisation des vues, templates, formulaires et modèles Django, confor-
mément aux principes MVC exposés dans la première partie, est illustrée au fil de l'étude de cas. ~annexe complète le manuel par une descrip-
tion pas à pas de l'installation de l'environnement de développement, tant sous Windows et Mac OS Xque sous GNU/Linux : Python, Django,
Eclipse, PyDev et les Web Developer Tools.
Àqui s'adresse ce livre ?
• Étudiants en informatique (IUT, écoles d'ingénieurs) et leurs enseignants;
• Développeurs web (PHP, Java, etc.) qui souhaitent passer à Python & Django ;
•Développeurs C, (++qui souhaitent une introduction systématique à la programmation web.
Au sommaire
Fonctionnement d'un site web • HTIP et notion de serveur web • Statique versus dynamique • Passer des paramètres à une page •
Programmation orientée objet et framework MVC •Modularité, simplicité et réutilisabilité •Travail d'équipe• Cos d'utilisation (use
cases)• Séparation modèle·vue·contrôleur • Le langage Python • Déclaration et initialisation des variables• Types et tronstypage •Copie
de variables • Opérations sur les types simples int, floot et string • Listes et dictionnaires • Instructions conditionnelles et boucles while •
Fonctions• Variables locales et globales• Classes et objets• Variables de classe (attributs statiques) et d'instance• Héritage et polymorphis-
me• Accès aux bibliothèques Python avec import et from • Structurer les pages avec HTMLS • Encodage• Balises et éléments HTML:
en-têtes, pieds de page et sections, liens hypertextes, listes, images, mise en évidence du texte, formulaires, etc.• Mettre en forme avec
les feuilles de styles CSS • Propriétés CSS et principes de sélection d'éléments (sélecteurs)• Dimension et imbri~otion des éléments•
Positionnement par défaut • Sortir des éléments du flux • Dynamiser les pages à la volée avec JavaScript • Evénements • DHTML,
jQuery et fromeworks JovoScript • Une étude de cas inspirée de Facebook • Cos d'utilisation et maquette du site (wireframes) •
Modèle de données et rappel sur les bases relationnelles• Clés primaires et étrangères• Relation 1-n, J. J et n-n •Correspondance relation-
nel/objet (ORM) •Diagramme de classes• Premier contact avec les bases relationnelles SQL •Un exemple en CGI: ce qu'il ne fout
plus faire• Les vues Django : orchestration et architecture • Configurer Django pour écrire du XHTML 5• Les templates Django:
séparation et réutilisation des rendus HTML • Langage des templates • Variables, sauts conditionnels et boucles, héritage et réutili-
sation de templotes • Les formulaires Django •~objet request •Formulaire de login •Gestion du message d'erreur • Lo bibliothèque
forms de Django •Valider l'adresse et le mot de passe• Les modèles Django •Créer Io base de données et le compte administrateur•
Regénérer Io base • Configurer l'interface d'administration de Io base de données • Générer des formulaires à partir de modèles
(ModelForms) • Comprendre et utiliser les sessions • Manier une variable de session • Authentification • Cookie versus session •
Protéger des pages privées• Des sites encore plus dynamiques grâce à Ajax • Annexe : installer l'environnement de déve·
loppement sous Linux, Mac OS X et Windows • Python, Django, Eclipse, PyDev et les Web Developer Tools.
Vl
Q)
0L..
>-
UJ
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
D ANS LA COLLECTION NOJRE
P. CtoJELSKL - Conception de systèmes d'exploitation. Le H. B ERS l.NI. La programmation orientée objet. Cours et
cas Linux. exercices en VML 2 avec Java 6, C# 4, C+ +, Python, PHP 5
N°G 11479, 2' édition , 2004, 680 pages. et LinQ.
J. E NGELS . HTMLS ET CSS3. Cours et exercices corrigés. N°l2806, se édition, 2011, 644 pages.
N°13400, 2012, 550 pages. É. S ARRION. - jQuery et jQuery UI.
G. Sw1NNEN . Apprendre à programmer avec Python 3. N° 12892, 201 1, 132 pages.
N°l3434, 3c édition , 2012, 435 pages. A . B RLLl, ANT. XML - Cours et exercices.
N°12691 , 2<édition , 2010, 336 pages.
Développer soi-même son site web avec HTML, CSS, PHP, JavaScript
R. R rMELÉ. -HTML5. R. R nvtELÉ. - Mémento HTMLS.
N°12982 , 20 11, 600 pages. N°13420, 20 12 , 14 pages.
F. D RAJLLARD. -Premiers pas en CSS et HTML. R. G OETTER. - Mémento CSS 3.
N°13338, 2011 , 464 pages . N°13281 , 2011 , 14 pages.
R. GoETIER. -CSS avancées. Vers HTML5 et CSSJ. É. DASPET et C. PrnRRE D E G EYER . PHP S avancé.
N°13405, 2• édition , 2012, 385 pages. N°l3435 , 6<édition , 2012, 870 pages.
R. Goen ER. - CSS 2: pratique du design web. C. P oRTENEUVE. - Bien développer pour le Web 2.0.
N°12461, 3c édition, 2009, 340 pages. N°12391 , 2<édition , 2008, 674 pages.
Apprendre
la programmation web
avec
Pt on
e,D·an o
Principes et bonnes pratiques
pour les sites web dynamiques
Vl
Q)
0L..
>-
UJ
N
.-f
0
N
@
......
..c
en
ï::::
>-
0
a. EYROLLES
u
ÉDITIONS EYROLLES
61, bd Saint-Germain
75240 Paris Cedex 05
www.editions-eyrolles.com
Vl
Q)
0
1-
>-
ll.I
N
M
0
N
@ En application de la loi du 11 mars 1957 , il est interdit de reproduire intégralement ou partiellement le présent ouvrage,
~ ,
~ sur quelque support que ce soit, sans l'autorisation de !'Editeur ou du Centre Français d'exploitation du droit de copie,
·~ 20, rue des Grands Augustins, 75006 Paris.
~ © Groupe EyroUes, 2012, ISBN: 978-2-212-13499-5
u
Avant-propos
Cet ouvrage se base sur Django, un outil de création de sites dynamiques écrit en Python, langage
aujourd'hui très populaire pour apprendre à programmer. Ce livre enseigne la programmation web
de façon aussi moderne que possible et s'adresse aussi bien aux enseignants qu'à leurs élèves. Il vous
demande peu de pré- requis, mais reste ambitieux, de sorte que vous n'aurez pas à rougir devant les
professionnels.
Vl
Q)
0L.. SOMMAIRE
>-
UJ
~ Résumer l'ambition de ce livre
N
..-!
0 ~ Resituer Django et Python dans l'évolution des technologies logicielles
N
@ ~ À qui s'adresse ce livre
......
..c ~ Plan de louvrage
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Il y a vingt ans, on déambulait entre les pages du Web comme entre deux tableaux de maître dans un
musée ; seule différence, on était assis face à son écran, souris à la main. Au fil des clics, les sites web
s'affichaient: ils étaient déjà jolis et colorés, riches en information et éminemment utiles ... mais inalté-
rables et rétifs à toute autre forme d'interférence que ce vagabondage de page en page.
Il était impossible pour l'internaute d'y écrire son numéro de carte de crédit pour acquérir une toile, de
réserver sa place pour une visite du musée, de s'enregistrer comme utilisateur du site et d'épingler sur le
sourire de Mona Lisa un commentaire ou des moustaches. Vous reveniez sur la même page quelques minu-
tes plus tard ? Le contenu était inchangé. Tout était placidement statique ; en un mot, le Web fonctionnait
pour l'essentiel dans une seule direction : des serveurs d'information vers les clients. Les utilisateurs étaient
à la merci de ce que les développeurs côté serveur avaient choisi de leur dévoiler. Le serveur ne percevait
que le clic d'entrée dans le site et se bornait à renvoyer en retour la page sollicitée; il était sourd et indiffé-
rent à toute autre requête. Le Web d'alors, certes impressionnant et révolutionnaire, était statique.
James Gosling, le concepteur du langage de programmation Java (dont le succès devra beaucoup au
Web), présenta en 1995 un nouveau concept de navigateur lors d'une conférence consacrée au Web. Il fit
d'abord apparaître la représentation en 2D d'une molécule dans un navigateur web classique, laissant
l'assistance de marbre. Quels ne furent la surprise et l'enthousiasme de ce même public lorsqu'à l'aide de
sa souris, il se mit à bouger la molécule ! Elle réagissait aux stimuli de la souris, obéissait aux injonctions
de l'internaute. Un programme Java, appelé « applet », s'exécutait dans le navigateur (Mosaic, à l'épo-
que) rendant cette interaction effective. Le Web venait de gagner ses premiers galons de dynamisme et
d'interactivité. Il en devenait chatouilleux.
En 2004, prenant conscience que l'utilisateur passait de spectateur passif à acteur essentiel du fonction-
nement du Web, sursaturant ce dernier de ses vidéos de vacances, son savoir, ses copains de lycée ou ses
prises de position politique, Tim O'Reilly décida de couronner le Web 2.0. Ce nouveau Web, aussi royal
qu'il fût, devenait complètement assujetti au bon vouloir de ses sujets qui, au-delà des sempiternels clics
de navigation, pouvaient dorénavant commenter, pérorer, refuser, voter, voler, acheter, vendre, négocier,
réserver, prêter, jouer, écouter, visionner, projeter, et tant d'autres activités encore l'éloignant de l'écran
de télévision pour celui de son PC. La confiscation du Web par cette multiplicité d'ego, choisissant d'en
faire cette excroissance narcissique qu'il est devenu, fut considérée à ce point révolutionnaire que le
célèbre hebdomadaire américain« Time »choisit d'élire You la personne de l'année 2006.
L'affichage d'un site web selon le bon vouloir de son créateur nécessite la maîtrise
d'un langage de présentation de contenu appelé HTM L (XHTML ou HTM LS,
vous comprendrez ces nuances par la suite), décrivant et paramétrant l'organisation
de la page, la taille et le style des différents éléments de celle-ci. C'est le seul langage
compris par les navigateurs, qui affichent la page de la manière précisée et transmise
dans les instructions HTM L.
Vl
Q)
Rendre la page « dynamique » requiert, de façon un peu plus exigeante, la maîtrise d'un
0L..
>- langage de programmation comme il en existe malheureusement trop: JavaScript,
UJ
N
C++, Java, .Net, Python, PHP, Ruby, SmallTalk, Eiffel, OCaml et tant d'autres. Ainsi,
.-f
0 la mise en place d'un site web dynamique capable de se comporter comme un pro-
N
gramme, réagissant comme il se doit aux sollicitations de son utilisateur, exige de mixer
@
...... ces deux savoirs dans une proportion dépendant de l'attention accordée soit à son inte-
..c
en ractivité, soit à son apparence.
ï::::
>-
a.
0
u
Avant-propos . .
H eureusement, depuis l'apport pionnier des applets et des servlets Java, de multiples
technologies logicielles sont apparues afin de combiner efficacement programmation
et physionomie d'un site. O!ii, dans le monde informatique, n'a entendu parler de
PHP, JSP (dans la mouvance Java) ou ASP.Net (offre de Microsoft), qui structurent
les milliards de sites interactifs disponibles aujourd'hui sur le Web ? Au-dessus de ces
langages apparaissent de multiples boîtes à outils logicielles facilitant la conception
des plates-formes web: Symfony et Zend pour PHP, Spring pour Java et, sujet de ce
livre, Django pour Python.
Elles font partie de ces multiples solutions, relativement équivalentes (même si bien
entendu leurs concepteurs s'en défendront avec vigueur), facilitant la prise en charge
conjointe de la présentation de la page et de son interactivité.
Bien que ces différentes technologies puissent également s'implémenter côté client,
cet ouvrage portera principalement sur celles qui s'exécutent côté serveur, les plus
sollicitées. Le code exécuté côté serveur a pour mission de produire à destination du
client une page répondant à ses desiderata. Pour ce faire, il est fréquemment néces-
saire d'obtenir et d'exploiter des informations stockées dans une base de données
relationnelle et de glisser ces dernières de manière judicieuse entre les instructions
HTMLS qui se chargent de clairement les présenter.
0L..
>-
UJ Le choix de Python et de Django
N
..-!
0
N
D epuis quelques années, grâce à Python et Django, il est devenu possible d'aborder
@ en douceur le cocktail de technologies informatiques à la base de la programmation
..... web. Ils ont pour eux la simplicité d'utilisation. Ainsi, le langage Python est très sou-
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
vent plébiscité pour sa facilité d'usage, sa rapidité d'acquisition, ce qui en fait un lan-
gage de prédilection pour l'apprentissage de la programmation. Son utilisation est
élémentaire à démarrer et très interactive. Les instructions étant plus simples et plus
intuitives, on parvient plus rapidement au résultat escompté. Bien que l'exécution de
ces codes conduise au même message à l'écran, print ("Hello World") en Python est
incontestablement plus simple à écrire mais aussi à comprendre que le fameux
publ ic static voici main (Stri ng[] args) {System . out .pri nt l n "Hello World"} rédigé
avec stupeur par tous les débutants en programmation Java.
Langage de programmation disponible pour plusieurs plates-formes, Python est
donc simple d'emploi : pas de typage explicite, instructions concises, structures de
données d'un usage élémentaire (listes, dictionnaires et chaînes de caractères). Pour
autant, il n'en préserve pas moins les fonctions essentielles de tout langage réputé
puissant. Il semble, un peu mieux que les autres, réussir à concilier efficacité et sim-
plicité, à se positionner entre ces deux acteurs exigeants que sont, d'une part, le pro-
cesseur qui cherche l'efficience et l'économie de mémoire et, d'autre part, le pro-
grammeur qui cherche la simplicité et la clarté d'utilisation.
Django, entièrement développé et basé sur le langage Python, fut à l'origine développé
pour faciliter et accélérer la programmation de sites web dans un milieu journalistique
(le journal Lawrence Journal-World publié quotidiennement dans la ville de Lawrence
au Kansas), donc pas vraiment versé dans les technologies de développement logiciel.
Les sites web en question exigeaient d'être développés et mis à jour à un rythme très
élevé ; les outils devaient pour cela être faciles à prendre en main et les logiciels produits
aisément réutilisables. Il était de surcroît préférable de séparer le métier d'ergonome de
sites web, préoccupé pour l'essentiel par l'apparence et la physionomie du site, du
métier de développeur, préoccupé par le fonctionnement optimal et sécurisé d'un code
Vl
Q)
dont l'écriture devait rester très abordable et facilement modifiable.
0L.. Django est devenu cette boîte à outils logicielle (framework dans le jargon profes-
>-
UJ sionnel), ce canif suisse du développement web. Aujourd'hui, cette aventure se pro-
N
.-f longe selon le modèle collaboratif de l'open source, impliquant des dizaines de mil-
0
N liers d'utilisateurs et de développeurs passionnés tout autour de la planète.
@
......
..c
en
ï::::
>-
a.
0
u
Avant-propos . .
import sqlite3
import cgi
mentales pourtant assez faciles à tenir distinctes, trois langages dont l'usage correct
évite ce charabia pénible. Ces trois langages sont le SQJ., pour la gestion et l'interro-
gation des bases de données relationnelles, le Python pour la programmation et le
HTMLS pour l'affichage et l'apparence des pages web.
C'est le pari réussi de Django de maintenir ces trois réalités informatiques suffisam-
ment différentiables pour, par exemple, épargner à l'artiste des pages web les subti-
lités du stockage relationnel et les joies de la programmation. D e surcroît, adopter
une technologie alternative d'affichage ou de stockage de données devrait laisser suf-
fisamment inaltérés les autres aspects du développement, contribuant ainsi à stabi-
liser l'intégralité du développement (souci essentiel d'une informatique dont les tech-
nologies ne cessent d'évoluer et de projets logiciels dont le cahier des charges se
modifie en continu). Cette séparation découle d'une recette de conception bien
connue des informaticiens et dénommée MVC (Modèle Vue Contrôleur), que nous
aurons l'occasion de présenter largement par la suite, recette qui facilite à la fois la vie
du développeur et celle de l'enseignant de cette pratique de développement.
développeur web, ses recettes, ses exigences, et les multiples solutions logicielles
capables de leur mâcher la besogne.
• La troisième cible pouvant tirer profit de la lecture de ce livre comprend les profes-
sionnels impliqués dans le développement web en quête d'une entrée en douceur
dans cet univers technologique somme toute assez exigeant. Même si leur environ-
nement professionnel les contraint à l'une ou l'autre technologie web différente de
Django (basée sur ASP.Net, Java/JSP, PHP, Ruby on Rail ... ), ce qu'ils découvriront
à la lecture de ce livre, (les différentes technologies de programmation, stockage
relationnel, modèles en HTML ou en CSS, le besoin d'une claire séparation entre
elles, la réutilisation de fonctionnalités) leur demeurera d'une grande utilité. Et
pourquoi pas, si cette liberté leur est offerte, ils pourront faire le choix de Django
pour leur entreprise, plateforme logicielle légère et formidablement réactive ! Pierre
Alexis, l'autre auteur de ce livre qui assiste Hugues Bersini dans son enseignement,
peut en témoigner dans cet ouvrage commun !
Le plan du cours
RESSOURCES EN LIGNE Code source du projet Trombinoscoop
Le code source du site développé dans le livre est librement téléchargeable depuis la fiche du livre sur le
site des éditions Eyrolles.
~ www.editions-eyrolles.com/livre/9782212134995
Notre propos est découpé en deux grandes parties : nous présentons d'abord l'essen-
tiel des aspects théoriques pour ensuite décrire en détail un projet concret.
La première partie a comme objectif de vous donner toutes les bases indispensables
pour comprendre ce qu'est un site web et comment il fonctionne. Nous y présentons
à la fois des notions théoriques (web dynamique, MVC, programmation objet, bases
de données relationnelles) et les langages nécessaires à leur mise en œuvre (HTML5,
CSS, JavaScript, S~, Python).
• Le premier chapitre aborde les rudiments théoriques de la programmation web :
Vl
Q) HTTP, URL, notions de Web statique et dynamique, de serveurs web et de ser-
0L.. veurs de bases de données.
>-
U.J
N
• Le chapitre 2 insiste sur la nécessité de séparer les tâches de programmation, de
..-!
0 présentation et de structure/stockage des informations. Nous y présentons le
N
modèle MVC et la programmation orientée objet. Nous expliquons en outre la
@
...... notion de framework de développement et montrons en quoi l'utilisation d'un fra-
..c.
en mework tel que Django facilite la tâche du développeur.
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
0L.. • Le chapitre 8 sépare ce qui concerne la présentation du site. Les rendus HTML
>-
UJ
deviennent réutilisables. Cela se fait grâce aux « templates » de Django et corres-
N pond à l'aspect Vue du MVC.
.-f
0
N
• Le chapitre 9 traite séparément le transfert de données entre l'utilisateur et le site,
@ par l'intermédiaire des formulaires.
......
..c
en
ï::::
>-
a.
0
u
Avant-propos . .
Remerciements
Pierre et Hugues adressent à Xavier Devos, Gaël Rabier et Jonathan Unikowski leurs
remerciements les plus sincères pour leur suivi, leur relecture attentive et les nom-
breuses corrections et améliorations qui leur sont dues dans les pages qui vont suivre.
Un immense merci aussi à l'équipe éditoriale d'Eyrolles : Muriel Shan Sei Fan pour,
tout d'abord, y croire dur comme fer, et nous communiquer l'enthousiasme, les
repères et les balises essentiels à la bonne conduite d'un tel projet, Laurène Gibaud
et Anne Bougnoux pour le formidable travail de remaniement et Gaël Thomas ...
pour avoir transformé l'essai en une impeccable mise en forme.
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@
......
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
Table des matières
Avant-propos ................................................................................. V
Pourquoi cet ouvrage ? ............................................ VII
Le choix de Python et de Django .................................... VII
À qui s'adresse cet ouvrage? ......................................... X
Le plan du cours .................................................. XI
Remerciements ................................................. XIII
PREMIÈRE PARTIE
Les notions essentiel les ................................................. 1
1
CHAPITRE
Comment fonctionne un site web ? .. . ..... ...... ......... ..... ....... ....... ... 3
~'est-ce que le W eh ? .............................................. 4
Fonctionnement d'un site web statique ............................... 5
Le protocole HTIP ............................................. 7
L'URL, adresse d'une page web .................................... 8
Le serveur web : à la fois ordinateur et logiciel . . . . . . . . . . . . . . . . . . . . . . . ..... 9
Des sites web qui se mettent à jour tout seuls ............................. 9
Fonctionnement d'un site web dynamique ........................... 11
Utilisation d'une base de données .................................. 12
Passage de paramètres à une page web .............................. 13
A ..
•-Je b.1en compris
. ;>. . ............................................. . 14
Vl
CHAPITRE 2
Q)
0L..
Programmation orientée objet et framework MVC . ....... ...... ... 15
>- Des programmes modulaires ........................................ 16
U.J
N Une écriture simplifiée .......................................... 16
T"'f
0 Des modules réutilisables .. .. ... ............ ... .. ... .. ... ... .. ... 16
N
@
Un travail d'équipe facilité et plus efficace ............................ 16
..... Les langages orientés objet ....................................... 17
..c
en Les cas d'utilisation (use cases) etle MVC .............................. 18
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
3
CHAPITRE
Rappels sur le langage Python .. ..... ...... ........ ...... ...... ...... ...... ...... 25
Qyalités et défauts de Python ........................................ 26
Qyalité : la simplicité ........................................... 26
D éfaut : la simplicité ! ... .. .... . .... . .... . ... .. ... .. .... . .... . .. 27
Les bases : variables et mémoire centrale ............................... 28
Déclaration et initialisation des variables ............................. 28
Type des variables ............................................. 29
Modification et transtypage des variables . ... .. ............. .. ... .. .. 29
Copie de variables ............................................. 30
Se renseigner sur une variable ..................................... 30
Qyelques opérations surles types simples .............................. 31
Le type int ................................................... 31
Le type float .................................................. 32
Le type string ................................................. 33
Les types composites : listes et dictionnaires ............................ 34
Les listes .................................................... 35
Les dictionnaires .............................................. 36
Les instructions de contrôle ......................................... 37
Les instructions conditionnelles ................................... 37
Aiguillage à deux directions: instruction if(..) else . . . . . . . . . . . . . . . . . . . . . 37
Aiguillage à plus de deux directions: instruction if(..) elif(..) else . . .... . .. 39
Les boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
La boucle while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
La boucle far (..) in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Les fonctions ..................................................... 43
Les variables locales et les variables globales . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Vl
Q)
La programmation obj et ............................................ 45
0L. Les classes et les objets .......................................... 45
>-
UJ
L'association entre classes ........................................ 47
N Héritage et polymorphisme . . . ...... . . . . . .... . . . ...... . . . ...... . . . . 51
..-!
0
N
Import et from : accès aux bibliothèques Python . .. ... .. .... . .... . .... . .. 54
@
. b.ien compris
Ai-Je . >
. . ............................................. . 55
.....
.c
en
ï::::
>-
a.
0
u
Table des matières
4
CHA PITRE
Rappels sur HTMLS, CSS et JavaScript........................................ 57
Structurerles pages web avec HTML 5 ................................ 59
Le concept de « balises » . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Structure d'un document HTML . .. ... ... .. .. ... .. ... .. ... .. ... ... 63
L'encodage de la page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Qyelques éléments HT M L ...................................... 66
Principaux éléments de structuration HTML . . . . . . . . . . . . . . . . . . . . . . . . . 66
Éléments de structuration annexes: en- têtes, pieds de page et sections . . . . . . . 68
Les liens hypertextes . . . . . . . .................. ........... ......... 70
Les listes . . . . . . . . . . . . . . . . .................. ........... ......... 71
Les images . . . . . . . . . . . . . . .................. ........... ......... 72
Mise en évidence du texte . . . .................. ........... ......... 73
Les formulaires. . . . . . . . . . . .................. ........... ......... 75
Autres éléments HTML . . . . .................. ........... ......... 78
M ettre en forme avec les feuilles de styles CSS . .... .. ... . .... . .... . .... .. 78
Les propriétés CSS . . .... . .... . .... . .... . .... . .... . .... . .... . ... 79
LessBecteuœCSS . ... .. ... .. .. ... .. ... .. ... ... .. ... .. .. ... .. .. 79
Sélectionner toutes les balises de même nom. . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Sélectionner un élément particulier : id en HTML et # en CSS . . . . . . . . . . . . 80
Sélectionner quelques éléments de même nature: class en HTML et . en CSS . . . 81
Appliquer une propriété seulement quand l'élément est dans un état donné. ... 81
Combiner les sélecteurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Sélectionner tous les éléments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Lier CSS et HTML ............................................ 83
Placer le code CSS dans les balises HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Placer le code CSS dans l'en-tête du fichier HTML . . . . . . . . . . . . . . . . . . . . . 84
Placer le code CSS dans un fichier séparé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
D imensions des éléments en CSS .................................. 86
Imbrication des éléments (boîtes) . .. ... .. ... ... .. ... .. .. ... .. ... .. . 87
Positionnement par défaut des éléments en CSS .. ... ... .. ... .. .. ... .. . 88
Sortir certains éléments du flux .................................... 89
Application à un exemple concret plus complet . .. ... ... .. .. ... .. ... .. . 91
D ynamiser les pages web « à la volée» avec J avaScript ..................... 96
Vl
Q)
Les événements ............................................... 96
0L.. Langage de programmation de scripts ............................... 96
>-
UJ
Un premier exemple de D HTML .. ... .. ... .. ... .. .. ... .. ... ... .. . 97
N jQyery et les frameworks JavaScript .... . .... . .... . .... . .... . .... . .. 99
.-f
0
N
Ai-je bien compris ? .............................................. 101
@
......
..c.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
5
CHAPITRE
Mise en application : un site web inspiré de Facebook ......... 103
Notre site web: Trombinoscoop .................................... 104
Les cas d'utilisation ............................................... 105
Maquette du site : les wireframes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... .. .. 106
L'écran d'authentification . .. ... ... .. .. ... .. ... .. ... .. ... ... .. .. . 107
L'écran de création d'un compte .................................. 108
L'écran d'accueil .............................................. 108
L'écran de modification du profil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... 108
L'écran d'affichage d'un profil .................................... 108
L'écran d'ajout d'un ami ........................................ 108
Scénario complet du site ........................................ 112
Modèle de données et petit rappel sur les bases de données relationnelles ..... 113
Clé primaire et clé étrangère ..................................... 114
R elation 1- n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Relation 1-1 ...... . . . .... . . . ...... . . . . . .... . . . ...... . . . ...... . 116
Relation n- n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
La problématique de la mise en correspondance relationnel/objet ......... 118
Avec Django. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Retour au modèle de données de T rombinoscoop : son diagramme de classes .. 119
Des personnes : étudiants et employés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
... qui travaillent ou étudient à l'université. . . . . . . . . . . . . . . . . . . . . . . . . . . 120
... et qui échangent des messages avec des amis.. ....................... 122
Ai-je bien compris ? .............................................. 123
CHAPITRE 6
Premier contact avec les bases relationnelles et SQL
à partir d'un exe1t1ple en CGI .................................................... 125
Analyse du carnet d'adresses: des cas d'utilisation au modèle de données ..... 127
T rois cas d'utilisation simples .................................... 127
Maquette des écrans (wireframes) .... . .... . .... . .... . .... . .... . ... 127
Le modèle de données du carnet .................................. 127
Création de la base de données avec SQJ_,ite ........................... 129
Accès à la base de données via SQL .................................. 131
Vl
Q) Syntaxe des requêtes SQL les plus courantes .. ... ... .. ....... ... .. ... 131
0L.. Qyelques exemples liés à notre base de données ...................... 132
>-
UJ Réalisation du carnet d'adresses avec SQJ_, et CGI .. .. ... ............ ... 133
N
.-f Lancement d'un serveur web Python ............................... 133
0
N L'écran d'accueil de l'ULB ...................................... 135
@ La page principale du carnet d'adresses ............................. 136
.....
..c.
en
ï::::
>-
a.
0
u
Table des matières -
DEUXIÈME PARTIE
Mise en application avec Django .............................. 147
CHAPITRE7
Les vues Django : orchestration et architecture ..................... 149
Utilité des vues .................................................. 151
Le fichier urls.py ................................................. 152
Le fichier views.py ............................................... 153
Enfin ! Notre première page web en Django ........................... 155
Lancement de l'environnement Eclipse et création du projet ............. 155
Le fichier urls.py ............................................. 158
Le fichier views.py ............................................ 158
Importation de la fonction dans urls.py ............................. 160
Configuration de Django pour qu'il écrive du XH TML 5 ............... 160
Test de notre ébauche de site .................................... 161
Bel effort, mais... . ............................................... 163
Ai-je bien compris ? .............................................. 163
8
CHAPITRE
Les templates Django : séparation et réutilisation
des rendus HTML . . ...... ...... .... ... ...... ...... ..... ........ ....... ... . . ...... ....... 165
Principe des templates ............................................ 166
Notre premier template ........................................... 167
Dynamisons ce premier template .................................... 170
Le langage des templates .......................................... 172
Les variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ......... 172
Formatage des variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Sauts conditionnels et boucles .................................... 173
Vl
Q)
H éritage et réutilisation de templates .............................. 17 4
0L.. Et si on avançait dans la réalisation de Trombinoscoop? .................. 176
>-
U.J
Amélioration visuelle de la page de login .............................. 180
N Ai-je bien compris ? .............................................. 184
..-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
CHAPITRE 9
Les for111ulaires Django ............................................................. 185
Patron courant de gestion des formulaires ............................. 186
L'objet request .................................................. 187
Traitement du formulaire de login ................................... 188
Ajout du formulaire dans la vue .................................. 188
Gestion du message d'erreur ..................................... 189
Présentation du message d'erreur ................................. 190
La bibliothèque forms de Django .................................... 190
Création d'un formulaire avec la bibliothèque forms ................... 191
Intégration du formulaire dans la vue et le template .................... 192
Validation du formulaire ........................................ 194
Présentation des messages d'erreur ................................ 196
Validation de l'adresse de courriel et du mot de passe .................. 197
Faut-il se contenter d'un seul visiteur autorisé? ......................... 199
Ai-je bien compris ? .............................................. 199
CHAPITRE10
Les 111odèles Django .............. ..... ............ ....... ............ .......... ...... 201
Les modèles Django .............................................. 202
Création d'un premier modèle ...................................... 202
Le modèle Personne ........................................... 203
Configuration ............................................... 204
Création de la base de données et du compte administrateur (superutilisateur) . 205
Création des autres modèles et de leurs liens ........................... 207
Le modèle Message : relation 1- n ................................. 207
La relation « ami » : relation n-n .................................. 208
Les modèles simples Faculté, Campus, Fonction et Cursus .............. 209
Les modèles Employé et Étudiant: héritage ......................... 209
Le lien entre Faculté et Personne : relation 1-n ....................... 210
Regénération de la base de données ............................... 211
Utilisation des modèles ............................................ 211
Création et modification d'un enregistrement ........................ 211
Récupération de plusieurs enregistrements .......................... 212
Vl
Q) Tri des données .............................................. 212
0L.. Récupération d'un enregistrement unique ........................... 212
>-
UJ Suppression d'enregistrements ................................... 213
N
.-f Accès à des objets « liés » . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
0
N Remplissage de la base de données ................................... 214
@ Configuration de l'interface d'administration des bases de données ........ 214
.....
..c
en
ï::::
>-
a.
0
u
Table des matières -
11
CHAPITRE
Comprendre et utiliser les sessions......................................... 231
À quoi servent les sessions ......................................... 232
Les sessions selon Django .. . .... .. ... .. ... . .... . .... . .... .. ... .. ... 233
Utilisation d'une session ... . .... .. ... .. ... . .... . .... . .... .. ... .. ... 234
Configuration .. . .... . .... . .... .. ... . .... . .... . .... . .... .. ... 234
Maniement d'une variable de session .............................. 235
Enregistrement de l'utilisateur authentifié ........................... 235
Vérification que l'utilisateur est bien authentifié ...................... 236
Utilisation des données de la session ............................... 237
Oye trouve-t-on dans le cookie ? ................................. 238
Oye trouve-t-on dans la session ? ................................. 238
Protection des pages privées ..................................... 238
Amélioration de notre page d'accueil ................................. 239
Personnalisation de la bannière ................................... 240
Division du corps de la page .. .. .... . ........ .. ... .. ... .. .... . ... 243
Liste des messages ............................................ 245
R écupération des messages de la liste. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Présentation de la liste des messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Liste des amis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Vl
Q)
Publication d'un message à destination de ses amis .................... 250
0L.. Ai-je bien compris ? .............................................. 251
>-
UJ
N CHAPITRE 12
.--!
0
N
En f inir avec Tror11binoscoop .................................................... 253
@ La page d'ajout d'un ami ........................................... 254
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Ajout d'un formulaire dans forms.py ... .. ........ . .... .. ... .. ... .. . 254
Création de la vue add_friend .................................... 255
Création du template add_friend.html ............................. 256
Ajout d'une URL dans urls.py ................................... 256
Ajout du lien dans la page d'accueil ................................ 256
La page de visualisation d'un profil ................................... 257
Création du template show_profile.html ............................ 258
C réation de la vue show_profile . . .... . .... . .... . .... .. ... . .... . .. 259
Ajout de l'URL dans urls.py ..................................... 260
Amélioration de la présentation dans style.css ........................ 260
Ajout des liens dans la page d'accueil .. . .... . .... . .... . .... . .... . .. 260
La page de modification d'un profil .................................. 262
Création du template modify_profile.html .......................... 262
Création de la vue modify_profile ................................. 263
Ajout de l'URL dans urls.py ..................................... 264
Ajout des liens dans la page d'accueil .............................. 264
Ai-je bien compris ? .... . .... . .... . ... . .... . .... . .... .. ... . .... . .. 265
CHAPITRE13
Des sites web encore plus dynamiques avec Ajax .................. 267
Exemple de l'interactivité attendue entre client et serveur . .... . ........ .. . 268
Validation de la création d'un compte avec Ajax ........................ 271
Ajout d'une URL pour la requête Ajax ............................. 272
Vue traitant la requête Ajax ..................................... 272
Ajout du code J avaScript ....................................... 274
Détecter que l'utilisateur a bien terminé de remplir le champ courriel . . . .. . . 274
Validation du courriel saisi . ........ . . . .... . . . ........ . . . ...... . . . 276
Insérer la liste des erreurs au-dessus du champ «fautif» ... . . . . . ........ . 277
Ajout d'un ami via Ajax ........................................... 279
Ajout d'un champ texte et d'un lien ................................ 279
Ajout de l'URL et de la vue ..................................... 280
Création du JavaScript d'ajout d'un ami ............................ 281
Insertion du HTML dans la page web ............................. 283
Conclusions .................................................... 284
Vl
Q)
Ai-je bien compris ? .... . .... . .... . ... . .... . .... . .... .. ... .. ... . .. 285
0L..
>-
UJ ANNEXE A
N
.--! Installation de l'environnement de développement ............. 287
0
N Oye faut-il installer ? ............................................. 288
@ Python ..................................................... 288
......
..c
en
ï::::
>-
a.
0
u
Table des matières M:tJ jj1
Django ... . .... . .... . .... . .... .. ... .. ... . .... . .... . .... .. ... 289
Eclipse ..................................................... 289
En résumé .................................................. 290
Installation de Python ............................................ 292
Pour Windows ............................................... 292
Pour Mac OS X .............................................. 295
Vérification de l'installation ..................................... 296
Installation de Django ............................................ 297
Pour Windows ............................................... 297
Pour M ac OS X .............................................. 299
Pour Ubuntu ................................................ 300
Vérification de l'installation ..................................... 301
Installation de Java ............................................... 302
Pour Windows et M ac OS X .................................... 302
Pour Ubuntu .... . .... .. ... . .... .. .... . .... .. ........ .. .... . . 302
Installation d'Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Installation du plug-in Eclipse PyDev ................................ 305
Installation de W eh Developer T ools pour Eclipse . . . . . . . . . . . . . . . . . . . . . . 310
Premier projet de test ............................................. 311
Ai-je bien compris? .............................................. 314
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@
......
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
Les notions
essentielles
Cette première partie vise à vous donner toutes les clés pour comprendre ce qu'est
un site web, comment il se construit et comment il fonctionne :
• protocole HTTP, U RL, notions de web statique et dynamique, serveurs ;
• programmation orientée objet, modèle MVC, notion de framework ;
• éléments de base du langage de programmation Python ;
• structuration des pages web avec HTML5, présentation avec les feuilles de sty-
les CSS, interactivité côté client avec JavaScript ;
• élaboration du modèle de données : cas d'utilisation (use cases), schémas de pré-
sentation (wireframes), bases de données relationnelles;
• éléments de base du langage d'interrogation de bases de données SQ!_.,, utilisa-
tion par le biais de l'ancienne technologie CGI, discussion des limitations de
cette dernière.
Vl
Q)
0L..
>-
UJ
N
.--!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
1
Comment fonctionne un site web ?
Ce chapitre rappelle les bases du Web, ses origines statiques et son passage graduel vers plus de
dynamisme avec, notamment, l'exploitation d'une base de données côté serveur, dont les mises à jour
se répercutent côté client. Sont également expliquées les notions d'URL, de protocole HTTP, de
serveur web et le passage de paramètres du client vers le serveur.
Vl
Q)
0L.. SOMMAIRE
>-
UJ ~ Petite histoire du Web
N
..-!
0 ~ Du Web statique au Web dynamique
N
~ URL, protocole HTTP et serveur web
@
..... ~ Passage de paramËtres vers le serveur
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Très souvent sont confondus les termes Internet et Web. Il n'est pas rare d'entendre l'expression erronée
«site Internet» pour désigner en réalité un «site web».
Internet est un réseau mondial permettant d'interconnecter des petits réseaux d'ordinateurs (d'où
l'appellation « Inter Network ») par l'intermédiaire de leur serveur. C'est grâce à Internet qu'un inter-
Vl naute situé en Belgique peut dialoguer avec un autre internaute localisé en Australie.
Q)
Le Web, quant à lui, n'est qu'une application d'Internet parmi d'autres comme le courriel, telnet (con-
0L..
nexion à distance sur un ordinateur) ou le peer-to-peer (de préférence légal).
>-
UJ En fait, il y a là deux réseaux superposés, mais de nature très différente : un réseau d'hyperliens « juste
N
.-f déposés » sur un réseau de connexions physiques. La page de votre voisin de bureau pourrait se trouver
0 à une vingtaine de clics de votre page web ; éloignés sur le Web mais proches sur Internet ou l'inverse,
N
@ les deux topologies ne se superposent pas.
......
..c
en
ï::::
>-
a.
0
u
Comment fonctionne un site web ?
CHAPITRE 1
Après son invention, très vite, le Web connut un succès grandissant et les premiers sites
web apparurent. Au départ très basiques, ces sites étaient pour la plupart résolument
«statiques». Un site statique se caractérise par des pages dont le contenu ne change pas
ou presque pas au fù du temps. I...:image suivante, représentant le site web de l'Université
libre de Bruxelles tel qu'il était en 1997, illustre très bien le concept de site statique.
Figure 1-1
Site web de l'ULB dans
sa version du 28 juin 1997
On le voit au premier coup d'œil, la page d'accueil est très simple et le contenu ne
semble pas destiné à varier au fù du temps. Revenez visiter le site dans un jour, une
semaine ou un mois, il est fort probable que la page n'aura pas changé d'un iota.
,_
0 Imaginons qu'un internaute désire se rendre sur la page web d'accueil du site de
>- l'Université libre de Bruxelles, dont l'adresse est www.ulb.ac.be/homepage (cette adresse
w
N est fictive, inutile de l'essayer dans votre navigateur).
.--1
0
N
@
~
.c
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Pour ce faire, sur son ordinateur, l'internaute va ouvrir un na·vigateur web (G oogle
Chrome, Safari, Internet Explorer, Firefox ou autre) et saisir www.ulb.ac.be/homepage
dans la barre d'adresse.
Un navigateur est un logiciel côté client qui permet à l'internaute de dialoguer avec des logiciels serveurs
pour en obtenir des informations (pages web). li affiche les pages demandées et navigue entre elles par
le biais des hyperliens.
Rt®f tcHTTP
Système ~e fichiers
..
Ordinateur du visiteur
Se rend sur www.ulb.oc.btt/homepege
....
C:\ website\homepage
Mais où se cachent ces serveurs web ? Généralement dans des centres de traitement des
données (Data center en anglais), gérés par des entreprises spécialisées et qui peuvent
héberger de nombreux serveurs et sites web, souvent au bénéfice de plusieurs clients.
Dans le cas de l'Université libre de Bruxelles (qui, comme beaucoup d'universités,
possède plus d'espace que de moyens), le serveur web ne se trouve pas dans un centre
de données externe, mais en son sein même.
Une fois la connexion établie entre le navigateur client et le serveur web, le premier
va envoyer la requête suivante au second : «donne-moi la page d'accueil homepage s'il
te plaît». Comme il s'agit d'un site statique, le serveur web va simplement lire sur
son disque dur (ou plutôt dans son système de fichiers) le fichier contenant la page
web homepage et le renvoyer au navigateur. Pour notre exemple, nous avons imaginé
un fichier nommé homepage se trouvant dans le dossier C: \webs i te.
Une fois la page transmise par le serveur au client, le navigateur va en décoder le con-
tenu et l'afficher à l'écran.
On le comprend aisément, à moins de changer le contenu du fichier homepage qui se
trouve sur le disque dur côté serveur, la page web renvoyée sera toujours la même. Le
seul dynamisme sera dû à l'informaticien chargé de mettre à jour les pages web stoc-
kées sur le serveur ... Beau mais dur métier, même pour un professeur à la retraite !
Autant l'automatiser.
Le protocole HTIP
Afin que le navigateur et le serveur web puissent dialoguer et se comprendre, il a fallu
définir ce qu'on appelle un protocole, qui détermine le langage et le vocabulaire utilisés
pour communiquer.
DÉFINITION Protocole
Un protocole définit la signification des bits échangés entre les deux machines interlocutrices.
Le protocole utilisé pour accéder à un site web est appelé HTTP (Hypertext Transjèr Pro-
tocob. Il définit par exemple comment doit être formatée la commande« donne-moi la
Vl
Q)
page homepage »que le navigateur envoie au serveur de l'université lorsqu'on tape l'adresse
0L.. www.ulb.ac.be/homepage. En réalité, la commande envoyée est transformée en celle-ci:
>-
UJ
N
EXEMPLE 1.1 Traduction de la commande en HTTP
.--!
0
N GET /homepage HTTP/1 . 1
@ Host : www . ulb . ac . be
......
..c
1
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Cette commande est appelée une requête HTTP. La réponse donnée par le serveur
(dans notre cas, la page web demandée) est appelée une réponse HTTP. La réponse
aurait pu ne pas être la page web demandée, mais, par exemple, une erreur indiquant
que celle-ci n'existe pas (d'où le recours au protocole qui fera parfaitement la diffé-
rence entre ces deux messages renvoyés par le serveur).
L e protocole utilisé étant HTTP, pour désigner le navigateur on parlera parfois de
client HTTP, et pour le serveur, sans grande surprise, de serveur HTTP.
temps réel les cours d'actions cotées en bourse. Il vaut mieux, on le concevra aisé-
ment, que l'information sur le cours d'une action puisse se modifier au fù du temps.
Figure 1-3
Page du site web de Reuters
affichant le cours de l'action
Apple
- -" .
Cturt
......
t~(ilOllMI~
...
---
.,_ . 1=-
Si au début du Web les sites statiques satisfaisaient la plupart des besoins, ce n'est
vraiment plus le cas aujourd'hui. Certes, il en existe encore (notamment certains sites
non professionnels), mais ils ne forment pas la majorité de ceux présents sur le Web.
Certains sites, que l'on pourrait a priori croire statiques, sont de fait dynamiques;
pensons par exemple à un blog sur lequel l'auteur ne publie que très peu d'articles.
En réalité, les qualificatifs « statiques » et « dynamiques » dépendent de la manière
Vl dont sont fabriquées les pages web.
Q)
,_
0
>-
w D~FINITION Page web dynamique
N
...-1 Une page est dite dynamique dès que son contenu est calculé à la volée .
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Comment fonctionne un site web ?
CHAPITRE 1
-G
C:\website\s~ocks\abi.Java
'
Ordinateur du visiteur
~ rend sur h11p://www.reuters.com/Sloch/ot>I
•'
Tout comme pour un site statique, le navigateur web côté client contacte le serveur
web de Reuters. Une fois la connexion établie entre le navigateur et le serveur, le pre-
mier envoie la requête suivante au deuxième : « donne-moi la page stocks/abi ».
Toutefois, le serveur ne va pas lire sur son disque dur un fichier contenant le contenu
de la page web. À la place, il lance un programme dont le rôle est de créer le contenu
de la page web demandée.
Vl
Q) Dans ce livre, nous utiliserons Python, mais ce programme peut être écrit en
,_
0 n'importe quel langage de programmation : Java, C, C#, etc. Sur l'illustration, nous
>-
w avons imaginé le programme écrit en Java et se trouvant à l'emplacement suivant sur
N
.--1 le disque dur : C: \webs i te \ s tecks \abi . java .
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Une fois la page produite par le programme, le serveur web l'envoie au client dans un
format compris par le navigateur (le même format qu'une page statique) . Ce dernier
en décode alors le contenu et l'affiche à l'écran.
- ~ --·--·
C:\website\siotks\abi.java Base de données
~
~
Figure 1-5 Création d'une page dynamique en utilisant une base de données
Sur ce schéma, la base de données se trouve sur le même serveur que le serveur web.
Comme les serveurs web, ceux en charge des bases de données sont interrogés à l'aide
d'un protocole bien déterminé.
Comme pour le serveur HTTP, le terme « serveur de bases de données » caractérise à
Vl
Q) la fois:
,_
0
• l'ordinateur physique sur lequel se trouve hébergée la base de données ;
>-
w
N
• le programme qui tourne constamment en arrière-plan dans l'ordinateur en ques-
.-1
0
tion et qui a pour mission de répondre aux requêtes des clients désirant consulter
N
ou modifier la base de données. Ce programme est appelé un Système de gestion
@
~
de bases de données (SGBD). Il en existe de nombreux sur le marché: MySQJ,,
.c
Cl'I Oracle Database, Microsoft SQJ, Serveur, PostgreSQL, DB2, etc.
·c
>-
0..
0
u
Comment fonctionne un site web ?
CHAPITRE 1
Un logiciel de gestion de bases de données peut se trouver sur une autre machine
qu'un serveur de bases de données dédié. On peut aussi installer sur une même
machine un serveur web et un système de gestion de bases de données. De multiples
répartitions des tâches sont possibles faisant usage de multiples serveurs.
De très nombreux sites web dynamiques ont recours à une base de données.
Figure 1-6
Exemple de page web
,,_.
+-
__ -
ou l'expression au départ de la recherche.
c •,.,,,. -~ --
- 0 •
avec un paramètre
Co glc ~~ .. - • + .l ·
_~U'-
.....L\l!:Qil)iltlVUl~
,t--1 t.........utb,.,.
ll'llt!M.11!..,,.Gtoup~;i~~olf'Oduclt.~&dl.c~ •Oiii.rlltC• mM
Pi1J11ô1Jt&-"•lllill"G*-' .............. ~.
·~~lon.C.....s~t.
_~·~
.....ll!!GW> EWllO~
Sstl09I ...
, .... ,......u ,.. & Mtna2!:!"'9
.... $.ohoay 91uswi1Schoocl: Cc.~s~ ~ S....<t-hetp. ..;..
...... ~)j·" -
Bk~Mlilwt. Plo,lt~ M9A ÛKW..~
~ !Mr~l\Vl'<l~a
"S6tyey
. . . . .. .....,...'S.., ....
Hl~~<-~ t011 tt6Qit toe..al • tMditie.()..of
M1Qt S61Yey a
le- ...,...~) Sol'ray •u"lidNt~dtlaef-..,,.,._
PJ9ften.-ll"Ç:ait
..
-
""'~ C9'Q twvpg;r dt CQQQD IAl!cay · Qaoop Acgytfs A' AMtA
._
"--~ ....,.. • ....,....awll0(_11.t41"5011t}'21.!~..,.,....
COl"•~"'COUl'f•f...Mlflt ~ ~1 14111J•t..mlaif# -~. . . .
~·r1101CW1s-., .. f-...•1:1t
Comment ce paramètre est-il passé à la page ? Pour le savoir, analysons plus en détail
Vl
Q) l'URL qui est appelée. On voit en haut de la capture d'écran que l'adresse est en réa-
,_
0 lité http://www.google.be/search?q=Solvay (cette adresse n'est pas fictive, vous pouvez
>-
w l'essayer dans votre navigateur).
N
.--1
0
Le paramètre est donc ajouté à la fin de l'URL. Pour séparer le nom de la page des
N
paramètres qui suivent, on fait usage du point d'interrogation. Ensuite, pour chaque
@
~
paramètre, on spécifie un nom (dans notre exemple le paramètre s'appelle q) et une
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Si l'on résume, les URL contenant des paramètres sont construites selon la forme
suivante:
C:\website\search.java
avtt lt. pora~trl q;aso/vay
Ordinateur du visiteur
S.. rtrrd sur http://www,'JOOIJlt..~/JtOr<h?q•solvay
,_
0
>-
w
Ai-je bien compris ?
N
..-1 • 01ielles sont les trois technologies qui furent inventées à l'origine du Web?
0
N
• Au niveau des traitements réalisés par un serveur web, quelle est la différence fon-
@
~
damentale qui d istingue un site web dynamique d'un site statique ?
.c
OI
·c
• Comment peut-on passer des paramètres à une page web ?
>-
0..
0
u
2
Programmation orientée objet
et framework MVC
Ce chapitre a pour mission d'expliquer la conception logicielle respectueuse du découpage MVC et sa
version sous Django. Nous exposons d 'abord les principes de la programmation orientée objet.
Ensuite, nous verrons comment la mise à disposition d'un .framework s'inscrit dans cette logique.
Vl
Q)
0L..
>-
U.J
N SOMMAIRE
T"'f
0 ~ Explication de la conception respectant le découpage MVC
N
@ ~ Mise en place du MVC sous Django
.....
..c ~ Explication de la notion de framework
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
EN PRATIQUE
La programmation orientée objet (OO) est fondamentalement distribuée, modularisée et décentralisée.
Et, pour autant qu'elle respecte également des principes de confinement et d'accès limité, elle favorise la
stabilité des développements, en restreignant au maximum l'effet des modifications apportées au code
au cours du temps.
L'orienté objet inscrit la programmation dans une démarche somme toute très clas-
sique pour affronter la complexité de quelque problème qui soit: une découpe natu-
relle et intuitive en des parties plus simples. A fortiori, cette découpe sera d'autant
plus intuitive qu'elle s'inspire de notre manière« cognitive» de découper la réalité qui
nous entoure. L'héritage, reflet fidèle de notre organisation cognitive, en est le témoi-
gnage le plus éclatant.
Figure 2-1
Une application •
avec juste un menu Undo
eut
Copy
Pas te
Dl?lete
Vl Select Al
Q)
,_
0
>-
w
N
.-1 Le code Python dont l'exécution affiche ce menu est repris ci-après, mais il est inu-
0
N tile à ce stade-ci d'en comprendre le fonctionnement en détail.
@
~
.c
Cl'I
·c
>-
0..
0
u
Programmation orientée objet et framework MVC
CHAPITRE 2
root = Tk()
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=O)
filemenu.add_command(label ="New", command=donothing)
filemenu.add_command(label ="Open'', command=donothing)
filemenu.add_command(label ="Save", command=donothing)
filemenu.add_command(label="Save as . . . ", command=donothing)
filemenu .add_command(label="Close", command=donothing)
filemenu .add_separator()
editmenu.add_separator()
menubar.add_cascade(label="Edit", menu=editmenu)
helpmenu = Menu(menubar, tearoff=O)
helpmenu.add_command(label="Help Index", command=donothing)
helpmenu.add_command(label="About .. . ", command=donothing)
menubar . add_cascade(label ="Help", menu=helpmenu)
root . config(menu=menubar)
root .mai nl oop()
Vl
Q)
0L.. L'affichage et l'utilisation d'un tel menu exigent la prise en compte de trois fonction-
>-
UJ nalités logicielles assez distinctes (mais pourtant en partie mélangées dans le code) :
N
.-f • le graphisme du menu (par exemple sa couleur, le nombre d'items qui apparaissent
0
N suite à l'activation du menu, le type de caractères utilisé pour les items du menu);
@
...... • les items qui composent le menu ;
..c
en • le fonctionnement du menu (qu'advient-il lorsqu'on choisit un des items ?).
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
On conçoit aisément que, même si le code affiché ne le fait délibérément pas, il est
préférable de tenir séparés ces trois aspects. Ainsi, on pourrait décider de modifier la
liste des items sans pour autant qu'il soit nécessaire de modifier la représentation du
menu ou l'exécution associée à certains des items. On devrait de même pouvoir aisé-
ment changer la couleur du menu sans affecter en rien son fonctionnement. On
pourrait même récupérer la liste des items pour un tout autre composant graphique,
un ensemble de « checkbox » par exemple.
Il en découle qu'il est plus logique et bien plus aéré que le haut du code se découpe
comme suit : d'abord la liste contenant tous les items, ensuite une boucle permettant
de créer les éléments graphiques associés à ces items.
root = Tk()
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=O)
for x in menultems :
filemenu .add_command(label =x, command=donothing)
Cet exemple, quoique modeste, montre bien la séparation des trois fonctionnalités
logicielles selon la recette de conception MVC. Ici, le modèle serait la liste des items
(que l'on pourrait installer dans un fichier séparé), la vue serait la représentation gra-
phique de ce menu (type de composant graphique pour afficher la liste, disposition
géométrique du menu, couleur et taille des items) et son contrôleur le mode de fonc-
tionnement du menu et des items qui lui sont associés (dans le code, la déclaration
séparée des fonctions donothi ng() ).
Autre avantage, un développeur tiers pourrait récupérer votre formidable menu, mais
pour une toute autre liste d'items. Imaginez le cas d'un restaurateur chinois qui vou-
drait récupérer le menu d'un collègue italien.
Figure 2-1
Distributeur
Diagramme « use case »
d'un distributeur automatique
Effectuer un
d'argent
virement
Banque
Effectuer la
Employé
Figure 2-2
Le modèle MVC et Use Case
<<interface>>
ô
<<contrôle>>
0
<<entité>
Enfin, les objets fondamentaux utilisés par l'application (qu'on appelle parfois objets
« métier »), tels que CompteEnBanque, Vi rement ou Client, seront représentés chacun
par une classe ou des éléments logiciels qui, in fine, s'associeront à des versions per-
manentes stockées sur disque dur (par exemple des tables c1 i ents et compte en banque
dans une base de données relationnelle).
Comme la figure ci-après l'indique, les éléments contrôles demeurent au centre de
tout et sont les éléments pivots de l'application. Les interfaces, reçoivent les sollicita-
tions des utilisateurs et s'adressent aux contrôles pour relayer ces dernières. À leur
tour, les contrôles parlent aux éléments entités (par exemple, ils vont chercher le
statut des comptes en banque ou créer de nouveaux virements) et sollicitent en retour
les éléments interfaces pour recevoir de la part des utilisateurs d'autres informations
Vl utiles à la continuation de l'interaction (combien retirer du compte, sur quel autre
Q)
compte effectuer le virement ... ).
,_
0
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Programmation orientée objet et framework MVC
CHAPITRE 2
Figure 2-3
MVC et distributeur
d'argent automatique
t0 t0
Compte
Bi que . Virement
--- ----~·~\----~
Django et le MVC *
Dans Django, les trois rôles modèle-vue-contrôleur sont joués respectivement par :
• les classes Modèles, qui s'occuperont de la mise en correspondance avec la base de
données relationnelle ;
• les temp1 ates HTML, qui permettront de coder en XHTML et CSS la visualisation
des pages web ;
• les fonctionnalités vi ew qui, par l'intermédiaire de méthodes P ython, s'occuperont
de toute la logique de fonctionnement de l'application.
Le framework Django
Vl
Q)
Un framework est une boîte à outils logicielle, un ensemble de solutions qui sont à
,_
0 votre disposition pour répondre le plus simplement possible à la plupart de vos
>-
w
besoins.
N
.--1
0
N ANALOGIE Une maison ouverte
@
~
La maison est à votre disposition, clé sur la porte ; il vous reste à décider du papier peint et des posters
.c de plage ou de voiture à punaiser au mur.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Par exemple, supposez que votre application gère des livres. Afin de créer une entité
1ivre avec son titre et sa date de publication dans la base de données relationnelle, il
suffira d'utiliser les modèles Django et d'écrire :
EXEMPLE 2.3 Modèle Django pour créer une dasse et une table livre
La création de cette classe Livre exige d'hériter (l'héritage en orienté objet sera
expliqué dans le chapitre suivant) de la classe mode 1s.Mode1 , qui fait partie en effet du
framework Django et qui se chargera de la mise en correspondance avec la table
1ivre associée dans la base de données relationnelle. Ce faisant, toute la gestion de la
base de données relationnelle vous est entièrement épargnée. Les amateurs de SQJ.,,
le langage d'interrogation des bases de données relationnelles, seront déçus sinon
frustrés, car les bibliothèques Django s'occupent de cette partie de l'application à leur
place. De même, pour obtenir les dix derniers livres parus, il vous suffit d'écrire une
méthode vi ew telle que :
EXEMPLE 2.4 View pour extraire les derniers livres de la base de données relationnelle
def dernier_livres(request)
liste_livres = Livre . objects .order_by(' - pub_date')[ :10]
return render_to_response('dernier_livre .html',
{'liste_livres' :l iste_livres})
Vl
Q)
0L..
>-
U.J
Ai-je bien compris?
N
..-! • Qyelle découpe propose le modèle de développement MVC ?
0
N • Qyelles sont les similitudes et les différences entre la découpe proposée par
@
...... l'approche orientée objet et la découpe MVC ?
..c.
en • À quoi sert un framework ?
ï::::
>-
a.
0
u
3
Rappels sur le langage Python
Ce chapitre a pour mission de présenter le langage de programmation Python, sur lequel repose le
projet Django. Les règles syntaxiques brièvement décrites ici devraient vous suffire pour comprendre
les dijférentes applications de Django que nous verrons par la suite, ainsi que pour maîtriser les
aspects « contrôle» de votre projet.
Vl
Q)
0L..
>-
UJ
N
SOMMAIRE
..-!
0 ~ Introduction au langage de programmation Python
N
@ ~ Les aspects procéduraux du langage
......
..c ~ Python et I'orienté objet
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Guido Van Rossum, inventeur et «superviseur» du langage Python, est hollandais d'origine, détenteur
de maîtrises en mathématiques et en informatique de l'université libre d'Amsterdam. Il fait partie, à la fin
des années 1980, d'un groupe de développeurs dont le but est de mettre au point un langage de pro-
grammation abordable par des non-experts, d'où son nom : « ABC ». Dès 1991, il s'attaque à Python,
écrit en C et exécutable sur toutes les plates-formes. Guido Van Rossum travaille alors au CWI (Centrum
voor Wiskunde en lnformatica). En 1995, il prend la direction des États-Unis et travaille pour le CNRI
(Corporation for National Research Initiatives) jusqu'en 2000. À cette époque, il publie Computer Pro-
gramming for Everybody, sa profession de foi pour l'enseignement de la programmation. C'est égale-
ment à cette période qu'il est nommé directeur des Python Labs de Zope Corporation, qui comprennent
aujourd'hui une demi-douzaine de développeurs.
Depuis 2005, il travaille pour Google, qui semble investir beaucoup dans le langage Python. Guido y
divise son temps de travail entre le projet Open Source Python et les développements de Google utilisant
ce langage. Il se targue de porter le titre très ambigu de Dictateur Bénévole à Vie. Ainsi, toute proposition
de modification du langage est débattue par le noyau et soumise à la communauté Python, mais la prise
en compte de celle-ci dans le langage reste la prérogative de Guido, qui conserve le dernier mot (d'où
son titre: gentil et à l'écoute ... mais dictateur tout de même, ces modifications n'étant pas soumises à
un vote majoritaire).
Qualité : la simplicité
Vl
Q)
En tant que langage de programmation, Python présente énormément de qualités liées
0L..
>- pour l'essentiel à sa facilité d'accès, de téléchargement et de mise en œuvre, à la clarté
UJ
N
de sa syntaxe, à son côté « open source », au fait qu'il soit interprété plutôt que compilé
..-!
0
puis exécuté, rendant possible de voir directement les résultats des instructions s'affi-
N
cher sans étape préalable de compilation. Python a visé dès son origine une grande
@
...... simplicité d'écriture, tout en conservant tous les mécanismes de programmation objet
..c
en de haut niveau. Il cherche à soulager au maximum le programmeur de problèmes syn-
ï::::
>-
a.
0
u
Rappels sur le langage Python . .
CHAPITRE 3
La communauté Python reste très structurée autour d'un seul site web.
~ http://www.python.org
C'est un atout considérable, surtout lors de l'apprentissage et de la découverte du langage: toutes les
sources restent accessibles et disponibles. Monsieur-tout-le-monde peut participer à l'évolution du pro-
duit, mais la prise en charge officielle des évolutions reste sous la responsabilité d'un seul. A quelques
subtilités près, Python est dans le prolongement de l'aventure Open Source, dont le représentant le plus
emblématique reste Linux. Il pourrait devenir le langage de programmation phare de l'open Source, tout
comme Linux est celui du système d'exploitation. Il semble que les éditeurs informatiques, tant Sun que
Microsoft, aient décidé d'évoluer pour leur propre bébé, vers ce même modèle de développement. Java
est en effet devenu Open Source et le projet Mono poursuit en Open Source l'aventure .Net.
Pour un retour aux sources du logiciel libre et de l'open source:
111 Richard Stailman et la révolution du logiciel libre - Une biographie autorisée, Eyrolles 2010
Python ne doit rien au reptile. Il se réfère aux humoristes anglais que sont les Monty Python, lesquels ont
révolutionné dans les années 1970 et 1980 à la fois l'humour et la télévision ; d'où la nécessité de les
remplacer par un jumeau ouvert sur le Web et la programmation !
Défaut : la simplicité !
Revers de la médaille, la simplicité de sa syntaxe se retourne contre Python ;
Vl
Q) l'absence de typage explicite et de compilation deviennent des défauts. Pour les criti-
0L.. ques, il est difficile d'aborder des projets complexes dans un idiome aussi primitif.
>-
U.J Peut-on écrire H amlet en Esperanto? C'est le Python se mangeant la queue!
N
..-!
0 Tout langage de programmation est toujours à la recherche d'un Graal au carrefour
N
de la simplicité d'usage et d'écriture, de l'efficience machine et de la robustesse. Au
@
..... vu du nombre et de la diversité des programmeurs, on peut douter qu'il soit possible
..c
en de le trouver un jour. Il est plutôt difficile de rationaliser ses préférences, et il en va -
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
presque ! - des guerres de langages comme de celles de religions. Nous ne nous posi-
tionnerons pas dans ce débat, Python nous étant de toute façon imposé par Django,
comme Java est imposé par la technologie JSP.
DÉFINITION Variable
Une variable est un nom servant à repérer l'emplacement précis de la mémoire centrale (l'adresse de cet
emplacement) où le programme stocke une donnée qu'il manipule.
Une variable peut être assimilée à une boîte aux lettres portant un nom. Par exemple, a=Ssignifie: « à
l'adresse mémoire référencée par a - autrement dit, dans la boîte aux lettres dénommée a - , se trouve
la valeur 5 ». Nous utilisons plus fréquemment l'abus de langage« la variable a vaut 5 ».
Étant donné la liberté autorisée dans le choix du nom des variables, il est préférable,
pour de simples raisons mnémotechniques mais également pour améliorer la lisibilité
des programmes, de choisir des noms de variables en fonction de ce qu'elles repré-
sentent réellement. Préférerez des dénominations parlantes telles que couleur, tai 11 e
OU pri X à x, y OU Z.
En Python, la simple déclaration d'une variable ne suffit pas à la créer. Après avoir
choisi son nom, il est nécessaire de lui affecter une valeur initiale.
monChiffre=S
petitePhrase= " Quoi de neuf ? "
pi=3 . 14159
maVariable = 5
maVariable = 2. 567
1
modifient simplement le contenu de la « boîte aux lettres » maVa ri ab1e. À la première
ligne, on indique qu'à l'adresse maVariable est stockée la valeur 5 et, à la seconde, on
remplace cette valeur par 2, 567. Après exécution des deux lignes, la valeur sauve-
gardée en mémoire à l'adresse maVari able est donc 2, 567.
Notons au passage que le type de maVa ri able a changé : il est passé de i nt à fl oat.
Cette spécificité est une facilité essentielle de plus permise par le langage Python. À
la différence d'autres langages de programmation plus contraignants, Python est dit
typé dynamiquement et non statiquement.
Avec le typage dynamique, il n'est plus nécessaire de préciser à l'avance le type des informations exploi-
tées dans le programme, celui-ci devenant« implicite ». Python devine le type par la valeur que nous ins-
tallons dans la « boîte aux lettres » - et ce type peut changer au fil des valeurs que la boîte va contenir.
Le choix entre typage statique et dynamique est de ces controverses qui ont amusé, distrait, même
déchiré, la communauté informatique depuis la nuit des temps (les années 1960 en informatique).
Copie de variables
Nous pouvons également prendre le contenu de maVa ri able et le copier dans
taVa ri able par la simple instruction :
Syntaxe
1 taVariable=maVariable
Le contenu de maVari ab 1e reste inchangé car il s'agit de recopier une valeur et non pas d'un
transport physique à proprement parler (ici la métaphore de la boîte aux lettres montre ses
Vl
limites). En fait, l'information est dupliquée d'un lieu de la mémoire vers un autre.
Q)
0L..
>-
UJ Se renseigner sur une variable
N
..-!
0 Si l'on comprend que la valeur affectée à une variable peut évoluer dans le temps, on
N
comprend tout autant qu'il est possible de réaliser toutes sortes d'opérations sur ces
@
..... variables, autorisées par leur type. Nous détaillerons pratiquement certaines de ces opé-
..c
en rations par la suite. Nous allons voir qu'outre l'abstraction offerte par les variables, le
ï::::
>-
a.
0
u
Rappels sur le langage Python -
CHAPITRE 3
langage nous offre toute une bibliothèque d'utilitaires. Citons d'ores et déjà deux fonc-
tions prédéfinies : type (nomDelaVari abl e) qui affiche le type de la variable mise entre
parenthèses et s'avère très utile pour vérifier ce qui y a été installé jusqu'ici, et pri nt
nomDelaVari able qui affiche à l'écran la valeur stockée à l'adresse désignée par la variable
nomDel aVariable .
Le type int
Le code suivant illustre des opérations réalisées dans la console interactive de
P ython, sur des variables de type entier (int).
SYNTAXE Commentaires
Les lignes débutant par # sont des commentaires en Python - donc non exécutés - et seront utilisées ici
pour éclairer le comportement des instructions.
Les »> que vous verrez apparaître par la suite sont produits par l'environnement de
développement et sont une « invite » à taper vos instructions Python. Les informa-
tions retournées par P ython sont présentées en italique.
>>> maVariable = 3
>>> print maVariable
3
>>> type(maVariable)
<type 'int ' >
»> taVariable=4
>>> maVariable=taVariable
>>> print maVariable
4
>>> maVariable = saVariable E)
Vl
Q)
#Une erreur apparaît car saVariable n'existe pas
0L.. Traceback (most recent call last):
>- File "<pyshell#23>", line 1, in <module>
U.J maVari able = saVariable
N
T"'f NameError : name 'saVariable' is not defined
0
N >>> maVariable = maVariable + 3 . ,
@ >>> maVariable #Dans la console interactive de Python, le seul appel de
...... #la variable suffit à donner sa valeur sans qu'il soit nécessaire
..c
en #d'utiliser print explicitement.
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
7
>>> maVariable = maVariable/2 C>
»> maVariable
3
#Python ne conserve que la valeur entière au vu du type de maVariable
>>> maVariable + 3 = 5 0
SyntaxError : can't assign to operator
#On ne peut pas écrire n'importe quoi et il faut respecter un minimum de
#syntaxe python.
>>> maVari able+=3 f)#Raccourci d'écriture ! ! !
>» maVariable
6
>>>
Outre l'affectation, les opérations mathématiques sur les valeurs contenues dans les
variables font partie des premières instructions élémentaires comprises par tout pro-
cesseur. Ainsi, ma Va ri ab l e=taVari ab l e+l signifie que la valeur contenue dans
maVa ri able va prendre celle contenue dans taVa ri able augmentée de 1 (ici, on est
plutôt en présence de deux classes d'instructions élémentaires : une addition et un
déplacement de valeur d'une variable à l'autre). Nous pouvons aussi constater que
l'expression maVariable=maVariable+3 signifie que la nouvelle valeur de maVariable est
égale à l'ancienne augmentée de 3 O . On peut d'ailleurs en raccourcir l'écriture:
maVariabl e+=3 f).
Nous pouvons d'ores et déjà répertorier deux formes d'erreurs. La première consiste à
effectuer des opérations sur une variable qui n'a pas été initialisée au préalable e.
Dans l'exemple, on ne peut en effet assigner la valeur de saVariable à maVariable car
aucune valeur n'a préalablement été assignée à saVa ri able. La ligne 0 , quant à elle,
montre que la liberté d'écriture n'est pas totale : il y a certaines règles de syntaxe et
conventions à respecter et nous en découvrirons d'autres par la suite.
>>> taVariable=3 . 0
>>> maVariable=taVariable/2 f)
»> maVariable
1. 5
>>> type(maVariable)
<type 'fl oat '>
>>> print maVariable
1. 5
>>> print mavariable 0
Traceback (most recent call last) :
File "<pyshel1#40>", li ne 1, in <module>
print mavariable
NameError : name 'mavariable' is not defined
Côté erreur, on peut ajouter que Python est sensible à la casse, c'est-à-dire différencie
majuscules et minuscules O : maVa ri ab1e et mavari ab 1e sont deux références diffé-
rentes. On peut également remarquer qu'une opération de division non entière sur
un entier naturel donne lieu à une troncature du résultat (ligne 0 dans l'exemple de
la section précédente), alors que la même opération réalisée sur un f1 oat (un réel)
donne lieu au résultat correct f). Retenons donc que 3 est int alors que 3.0 est float.
Le type string
Pour en terminer avec ces types simples, le code suivant illustre des exemples concer-
nant des variables de type string (des chaînes de caractères).
On constate ici que des opérations sur les littéraux sont possibles : le + en présence de
deux string sert à les concaténer 0 , alors que le * sert à répéter un littéral f). Remar-
quons également que la chaîne de caractères se présente comme une collection de
caractères indexés, le premier élément de la chaîne étant repéré par la valeur 0, le
second la valeur 1 e,
etc.
Enfin, remarquons qu'il est interdit de concaténer deux éléments de types différents,
par exemple un string et un nombre naturel Q . À nouveau, l'erreur se produira à
l'exécution vu l'absence de typage statique et d'une étape préalable de compilation.
Une chaîne de caractères se distingue par la présence des apostrophes. En l'absence
de celles-ci, la signification de l'expression peut être toute autre. Dans la ligne O,
c'est la variable phrasel (sans apostrophes) qui est prise en compte, alors que dans la
ligne 0 , c'est la chaîne « ph ras el » (entre apostrophes doubles) qui est affectée à la
variable phrase2 .
Contrairement à d'autres langages, Python ne fait pas de différence entre les apostrophes simples et les
doubles.
Vl
Les types composites : listes et dictionnaires
Q)
0L.. Nous avons jusqu'ici vu des données de types simples à savoir les int, les float et les
>-
UJ
string. Il existe également des types composites, qui regroupent en leur sein plu-
N sieurs entités de types simples.
...-!
0
N Nous en avons déjà vu un cas particulier. En effet, les chaînes de caractères sont des col-
@ lections de caractères, chacun de type string. Ici, toutes les entités sont du même type.
......
..c.
en
ï::::
>-
a.
0
u
Rappels sur le langage Python -
CHAPITRE 3
Les autres données composites qui nous intéresseront par la suite sont les listes et les dic-
tionnaires. I.:utilité de ces collections est de répéter un même traitement sur chacun des
éléments composant la collection. Par exemple, si l'on souhaite mettre toutes les lettres
d'un mot en majuscules, il serait stupide de réécrire cette opération autant de fois qu'il y a
de lettres dans le mot; autant ne l'écrire qu'une fois et placer cette opération dans une
boucle qui balaiera tout le mot. Collections et instructions de boucle vont souvent de pair.
Les listes
Nous avons vu que, dans une chaîne de caractères, chaque élément est indexé par une
valeur entière numérotée à partir de O. Les listes ne sont qu'une généralisation de ce
principe aux autres types : entiers, réels, caractères, chaînes. Le code suivant clarifie
leur utilisation.
0L.. On voit clairement 0 qu'une liste est une série cl'entités de types simples, chacune
>-
U.J étant accessible par l'intermédiaire de son index: 0,1,2 ... Attention à ne pas dépasser la
N
..-! longueur initiale de la liste f), déterminée lors de son initialisation. Pour ajouter un élé-
0
N ment en fin de liste e, il suffit d'utiliser l'instruction append, alors que pour insérer un
@ nouvel élément dans la liste en une position précise, il faut utiliser l'instruction
.....
..c
en
i nsert o.
I.:instruction l en retourne quant à elle le nombre d'éléments de la liste e.
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Les dictionnaires
Les dictionnaires, derniers types composites, sont quant à eux une généralisation des
listes. Chaque élément est indexé non plus par sa position dans la liste, mais par un
élément choisi parmi les trois types simples. Il s'agit donc d'une sorte de matrice
2 x n d'éléments simples dont ceux de la première colonne réalisent l'index ou la clé
(key) d'accès au second.
L'exemple traité dans le code clarifiera les idées.
vent à accéder à leur pendant dans la seconde. Vordre d'apparition des éléments n'a
plus aucune importance dans les dictionnaires car l'indexation de chaque élément ne
se fait plus par sa position.
if condition: O
blocl 0
else: O
bloc2 e
bloc3 e
Vl
Q) Vévaluation de la condition renvoie un résultat «vrai» ou « faux» ; on dit de cette
0L.. expression qu'elle possède une valeur booléenne. Le b1ocl O est un ensemble d 'ins-
>-
U.J tructions qui ne seront exécutées que si la condition est vérifiée. Si la condition est
N
T"'f fausse, c'est le bloc2 8 qui sera appliqué. D ans un cas comme dans l'autre, le pro-
0
N
@
gramme continuera en exécutant le b1oc3 e.
..... Remarquons la présence essentielle des deux-points 0 et du retrait devant b1ocl 0
..c
en et bloc2 f). Les deux-points marquent la fin de la condition. Toutes les instructions
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
DÉFINITION Indentation
On dit du code décalé vers la droite qu'il est indenté.
En Python, l'indentation est fondamentale. Elle fait intégralement partie de la syntaxe du langage. Ce qui
était une bonne pratique d'écriture de code, ayant pour finalité d'en aérer la présentation (et générale-
ment suivie par la majorité des programmeurs, tous langages confondus), s'est trouvée transformée en
une règle d'écriture stricte.
>>> a=S
»> if a<lO :
print "c'est vrai"
if a>lO :
a=6
print "c'est faux" 0
c'est vrai
>» if a<lO :
print "c ' est vrai "
if a>lO :
a=6
print "c'est faux" f)
c'est vrai
c'est faux
Vl
Q) Toutes les instructions à exécuter lorsque la condition n'est pas satisfaite doivent être
0L.. regroupées sous le mot-dé e1se.
>-
UJ
N
.-f
0 DÉFINITION Else
N
@ Else signifie <c autre » en anglais; e1se représente tous les cas non couverts par la condition du if.
......
..c
en
ï::::
>-
a.
0
u
Rappels sur le langage Python
CHAPITRE 3
>» a=lO
»> if a<lO:
print "a inferieur a 10"
el se:
print "a superieur ou egal a 10"
a superieur ou egal a 10
if condi tionl:
b7ocl
el if conditionZ:
b7oc2
el se:
b1oc3
DÉFINITION elif
On peut définir autant de situations disjointes qu'on le souhaite en ajoutant des blocs e1if.
Un des avantages du e1if est de pouvoir aligner toutes les conditions disjointes les
unes en-dessous des autres, sans être contraint de décaler de plus en plus vers la
droite à chaque condition (la largeur du papier n'y suffirait pas).
Les boucles
Ce type d'instruction permet au programme de répéter, de compter ou d'accumuler,
avec une économie d'écriture considérable.
La boucle while
La syntaxe de cette instruction est :
>» compteur = 0
>>> while compteur < 4:
pri nt compteur
compteur += 1
0
1
2
3
Bob
Jean
Pi erre
Alain
Vl
Yves
Q)
0L..
Muni de ces différents éléments, il est aisé de comprendre le code suivant, impli-
>-
UJ
quant un dictionnaire cette fois. Soit une collection d'étudiants, chacun ayant obtenu
N
.--!
0
une note à un examen. Le programme qui suit, dans lequel de nombreuses lignes ne
N
sont pas montrées, établit la moyenne des notes ainsi que le nombre d'étudiants
@
..... ayant raté l'examen. Sachez juste que for x,y in l i steEtudiant . items () permet de
..c
en boucler à la fois sur la clé (x) et sur les éléments indexés par celle-ci (y).
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
»> Moyenne = 0
>>> #On crée un dictionnaire des notes indexé par les étudiants
>>> listeEtudiant ["Pierre"] = 10
>>>
>>> NombreEtudiants=O
>>> NombreRates=O
>>> for x,y in listeEtudiant.items():
NombreEtudiants+=l
Moyenne+=Y
if y < 10 :
NombreRates += 1
>>> Moyenne/=NombreEtudiants
»> Moyenne
10 . 5
»> NombreRates
3
Le petit code qui suit est inspiré d'un «jeu à boire » comme bien des étudiants en ont
connu, notamment à l'Université Libre de Bruxelles, où on l'appelle le «ding ding
bottle ». Ce jeu simple consiste à énumérer les nombres à tour de rôle et, si le nombre
est un multiple de 5 ou de 7, le remplacer respectivement par «ding ding» ou
« bottle ». (On imagine que si chaque erreur est punie par l'ingurgitation cul sec d'un
verre, les erreurs s'enchaînent de plus en plus vite.) Voici une version Python d'une
sobriété sans égale de ce petit jeu décapant.
EXEMPLE 3.15 Ding ding bottle en Python
6
bottle
8
9
ding ding
11
12
13
bottle
ding ding
16
17
18
19
Les fonctions
D ans Python comme dans tous les langages de programmation, il est possible de
découper le programme en blocs fonctionnels, appelés « fonctions » ou
« procédures », qui peuvent être appelés partout dans le code. Ces fonctions rendent
le programme plus modulaire et plus clair en évitant des répétitions de blocs d'ins-
tructions parfois longs. Le comportement et le résultat des fonctions dépendront des
arguments reçus en entrée. I..:exemple simple illustré ci-après est la définition de la
fonction cube (x) qui renvoie le cube de l'argument x. A près avoir défini la fonction,
on l'appelle 4 fois à l'intérieur d'une boucle.
EXEMPLE 3.16 Fonction
>» compteur = 1
>>> while compt eur < 5:
cube(compteur)
compteur+=l
Vl
Q) 1
0L.. 8
>-
UJ 27
N 64
.--!
0
N
@ L'exécution de la fonction se termine en renvoyant le contenu du return 0 au code
...... appelant. O n pourra bien sûr appeler la fonction partout où cela s'avère nécessaire .
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
»> liste
[ ' naeJ ' , '1 uaP' , ' seuqcaJ ']
»> X=5 0
»> test(x)
6
>>> X
5
La programmation objet
self ._age=ageinit
self . adresse=adresseinit
def donneNom(self):
return self ._ nom
def donneAdresse(self):
return self . adresse
def donneAge(self) :
return "age : " + str(self ._age)
def _str_(self): ~
return "client : " + self._prenom + " " +self . nom
Résultat de l'exécution
>>>
client : Hugues Bersini
client: Pascale Lenders
client: Hugues Bersini
rue Louise
rue Juliette
age: 31
>>>
Vl
Q)
Le mot-clé se 1f est indispensable dès qu'il s'agit de faire référence à l'objet lui-même. De fait, toutes les
0L.. méthodes portant sur l'objet se doivent de recevoir ce dernier, c'est-à-dire se 1f , en paramètre.
>-
UJ
N
T"f
0 1: association entre classes
N
@ La pratique de !'orienté objet consiste d'abord et avant tout en l'éclatement de
..... l'application logicielle entre les classes constitutives du projet. Ainsi, si dans un logi-
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
ciel bancaire, le client veut retirer 1 000 euros de son compte en banque, c'est l'objet
client qui sollicitera la méthode retrait(lOOO) exécutée sur le compte en question.
Ce déclenchement de la méthode retrait sur le compte, provoqué par le client, est
appelé dans le jargon objet un «envoi de message». Tous les ingrédients d'un mes-
sage s'y retrouvent: l'expéditeur (objet client), le destinataire (objet compte en
banque) et le contenu du message (appel à la méthode retrai t(lOOO) ).
D ans le diagramme de classes UML représenté ci-après, chaque objet client est
associé à un ensemble d'objets compte en banque et, en retour, chaque objet compte en
banque est associé à un et un seul client. Cette association « 1-n » est bidirection-
nelle. Le code qui suit réalise cette association entre les deux classes. Son exécution
se limite à créer un client et un compte en banque, puis à permettre au client de
déposer un certain montant sur son compte. Pour ce faire, le client va envoyer le mes-
sage depose(lOOO) sur le compte qu'il aura sélectionné. Notez également l'apparition
d'attributs statiques dans la classe compte en banque : le modèle utile au numéro de
compte et le nombre de comptes créés (qui seront tout deux utilisés pour attribuer un
numéro de compte au client).
CompteEnBanque
Figure 3-1 Clients et comptes -solde
-numero
-modele
-nombreComptes
Client -monTltulalre: Client
-mesComptes: CompteEnBanque +_ inlt_ ()
-nom +retire(entrée montant : int)
-prenom +depose(entrée montant : int)
-adresse
1
-age
Vl
+_lnit_()
Q) +donneNom()
,_
0 +donneAdresse()
>-
w
+demenage()
+donneAge()
N
.--1 +vieillit()
0 +ajouteCompte(entrée nouveauCompte: CompteEnBanque)
N
+retire()
@ +depose()
~
.c
Cl'I
·c
>-
0..
0
u
Rappels sur le langage Python
CHAPITRE 3
class CompteEnBanque :
_modele="210- " #attribut statique
_ nombreComptes=O #attribut statique
def assigneîitulaire(self,titulaire) :
self ._monîitulaire =titulaire
def donneNumero(self) :
return self ._ numero
def retire(self,montant) :
self. solde-=montant
def depose(self,montant):
self. _ solde+=montant
class Client :
def donneAge(self) :
return "age: " + str(self._age)
def vieillit(self) :
self ._age+=l
def _str_(self) :
return "client : " + self ._prenom + \
" " +self. nom
def ajouteCompte(self,compte) :
self ._mesComptes . append(compte)
compte . assigneîitulaire(self)
def identifieCompte(self):
print ("Sur quel compte ?")
x=input ("?") #cette instruction permet de lire un string
#a 1 'ecran en affichant un "?"
for c in self ._ mesComptes :
if c.donneNumero() == x:
res=c
break
return c
def retire(self) :
c=self.identifieCompte()
print ("quel montant ?")
x=i nt (input("?"))
c. reti re (x)
def depose(self) :
c=self.identi fieCompte()
print ("quel montant ?")
x=i nt (input("?"))
#le string lu a 1 'ecran devra etre modifie en int
c . depose(x)
Vl
Q) #creation d'un premier client
0L.. clientl = Client("Bersini","Hugues","rue Louise",20)
>-
U.J
#creation d'un premier compte
N
comptel= CompteEnBanque()
..-!
0
print (comptel)
N #ajout du compte dans la liste des comptes du client
@ clientl . ajouteCompte(comptel)
......
..c
en
ï::::
>-
a.
0
u
Rappels sur le langage Python -
CHAPITRE 3
Résultat de l'exécution
>>>
le solde du compte 210-0 est 0
Sur quel compte ?
?210- 0
quel montant ?
?1000
le solde du compte 210-0 est 1000
>>>
Héritage et polymorphisme
En orienté objet, la deuxième manière de découper l'application en classes est de
recourir au mécanisme d'héritage qui permet de considérer les classes à différents
niveaux de généralité. On parlera ici de classes parents (ou super-classes) pour les
plus génériques et de classes filles (ou sous-classes) pour celles qui en héritent. L es
classes s'installent ainsi dans une taxonomie, des plus génériques aux plus spécifiques.
Les classes filles héritent des attributs et des méthodes de leurs parents et peuvent se
distinguer de trois manières :
• en ajoutant de nouveaux attributs qui leur seront propres,
• en ajoutant de nouvelles méthodes qui leur seront propres,
• en redéfinissant des méthodes déjà présentes dans les classes parents. La redéfini-
tion signifie qu'on reprend exactement la même signature de la méthode (nom et
argument), mais qu'on lui associe un code différent.
Dans le code et le diagramme de classes qui suivent, la classe Li vretEpargne hérite de
la classe CompteEnBanque, via les parenthèses. Elle ne possède en propre que deux attri-
buts statiques : le so 1deMi ni ma1 0 , en deçà duquel le client ne peut débiter son solde,
et un taux intérêt f). Elle ajoute une méthode particulière pour calculer son
intérêt e et elle redéfinit la méthode retire 0 en prenant en considération la con-
Vl
trainte du solde minimal. Si nécessaire, elle peut rappeler la méthode prévue dans la
Q)
classe mère (en la référant par CompteEnBanque . retire()). Par ailleurs, le solde étant
0L..
>-
privé dans la classe mère, il n'est accessible que par 1'entremise de la méthode
UJ
donneSolde() 9 . Ici, il n'est pas nécessaire de lever une ambiguïté sur l'appel en fai-
N
.--!
0
sant explicitement allusion à la classe mère puisque la méthode n'est pas redéfinie .
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
CompteEnBanque
Figure 3-2 Héritage de classe
-solde
-numero
-modele
·a2mbr!lC2m 1fü:~
Client -monîitulaire : Client
-mesComptes : CompteEnBanque ~+_init_()
-nom +ret ire(entrée montant : int)
-prenom +depose(entrée montant: int)
-adresse 1 6
-age
+_ init_ ()
+donneNom()
+donneAdresse()
+demenage()
+donneAge()
+vieillit()
+ajouteCompte(entrée nouveauCompte : CompteEnBanque) livretEpargne
+retire() -soldeMînimal
+depose() -interet
+catcullnteret()
+ret ire(entrée montant : int)
class LivretEpargne(CompteEnBanque):
~soldeMinimal=O ., #attribut statique
~interet = 0.1 f) #attribut statique
def retire(self,montant): ~
if (self .donneSolde() ~ - montant) >= \
LivretEpargne.~soldeMinimal:
CompteEnBanque . retire(montant)
#appel de la methode de la classe mère
el se:
print ("pas assez d'argent sur le compte")
Vl
Q)
Dans les instructions qui suivent, on voit que le client dépose d'abord 1 000 €sur son
,_
0 compte puis souhaite en retirer 2 000. Comme le compte en question s'avère un livret
>-
w
d'épargne et non un compte en banque quelconque, c'est bien la version redéfinie de
N la méthode retire du livret d'épargne qui sera appelée.
...-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Rappels sur le langage Python -
-------"--'----=-- -=---=--
CHAPITRE 3
Résultat de l'exécution
>>>
le solde du compte 210-0 est 0
Sur quel compte ?
?210-0
quel montant ?
?1000
le solde du compte 210-0 est 1000
Sur quel compte ?
?210-0
quel montant ?
?2000
pas assez d'argent sur le compte
>>>
DÉFINITION Polymorphisme
L'appel de la méthode redéfinie en fonction de la nature de la sous-classe sur laquelle cette méthode
s'exerce est appelé polymorphisme.
Vl
Q)
0L..
>-
U.J
N
T"'f
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
4
Rappels sur HTMLS,
CSS et JavaScript
Ce chapitre va s'intéresser aux langages de présentation des pages web, HTMLS et CSS, ainsi qu'à
la manière de rendre les pages plus interactives et plus dynamiques côté client, par l'utilisation du
javaScript. Ces trois technologies sont devenues incontournables, quelle que soit la plate-forme de
développement web choisie.
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
SOMMAIRE
@ ~ Synthèse rapide des technologies HTML5, CSS et JavaScript
......
..c ~ HTML5, CSS, JavaScript : pièces maîtresses du Web communes à tous les environnements de développement web
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Créer un site web, qu'il soit statique ou dynamique, c'est avant tout créer des pages
web. Ces dernières contiennent l'information que l'on désire partager et afficher.
D ans ce chapitre, nous allons étudier les langages et technologies qui permettent de
les construire.
Le premier de ces langages est HTML (HyperText Markup Language); il décrit le
contenu et la structure d'une page web. Nous nous intéresserons ensuite aux CSS (Cas-
caded Style Sheets), qui décrivent l'aspect d'une page web (couleurs, polices, position
des éléments, etc.). Nous terminerons par un aperçu de JavaScript, qui ajoute de
l'interactivité et du dynamisme aux pages web.
On retrouve à un autre niveau la fameuse trinité modèle-contrôle-apparence évoquée
au chapitre 2. Ici, c'est H TML qui s'occupe du modèle et de l'information à pré-
senter, les CSS de l'aspect et JavaScript du contrôle. La recette gagnante est de
séparer au mieux ces trois aspects du site web, de les confier à des spécialistes diffé-
rents et de jouer au mieux la division du travail.
Ces trois langages sont exécutés et interprétés côté client par le navigateur web,
a contrario de Python ou Java qui sont des langages exécutés côté serveur. Reprenons
le schéma vu au chapitre 1 pour mieux comprendre cette distinction.
Sur ce schéma, un internaute désire consulter le site de Reuters. Le serveur web de
Vl Reuters est contacté par le navigateur de l'internaute. J ava (il pourrait s'agir de
Q)
0L..
Python, ASP.N et ou PHP) entre alors en action pour créer la page à renvoyer ; plus
>- précisément, Java écrit le code HTML (accompagné de ses CSS et JavaScript) à ren-
UJ
N
voyer au navigateur. Le code Java est donc exécuté côté serveur. Lorsque la page web
.-f
0 parvient au navigateur, ce dernier en interprète le HTM L, les CSS et le JavaScript,
N
@
afin d'en construire son rendu graphique et de l'afficher à l'écran. Ces trois langages
...... sont donc exécutés côté client par le navigateur.
..c
en
ï::::
>-
a.
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
-~
C:\website\s1°cks\abi.java
Ordinateur du visiteur
S<t 1rnd sui h11p.//wWw.trutt1!.tt>m/st«ks/obl
•
Il n'est donc pas nécessaire d'avoir un serveur web pour construire une page web et
visualiser son rendu: on peut très bien composer la page à l'aide d'un éditeur HTM L
et la visualiser avec un navigateur, sans passer par un serveur web. C'est ce nous ferons
tout au long de ce chapitre pour tester nos pages H TML, CSS etJavaScript. Laissons
notre serveur se reposer un peu, nous ne tarderons pas à le solliciter de nouveau.
HTML est un langage relativement ancien (inventé à la fin des années 1980) et a beaucoup évolué au fil
de ses versions successives. Les premières années, il évolua sous l'impulsion des développeurs de naviga-
teurs. Par conséquent, aucune norme réellement formelle ne s'imposait et il fallait parfois compter avec
des implémentations différentes du langage d'un navigateur à l'autre. Vers le milieu des années 1990, un
effort de normalisation fut accompli par la création d'un consortium, le Wor/d Wide Web Consortium
(abrégé en W3C) dont la mission était, et est toujours, de normaliser les technologies du Web.
Au départ, HTML était destiné à représenter à la fois le contenu d'une page web et
son aspect graphique. À partir de la quatrième version du langage, dans l'esprit de
séparation des fonctionnalités, son rôle a évolué afin de se concentrer uniquement sur
le contenu et la structure de la page. L'aspect graphique n'était plus du ressort de
HTML, mais des CSS.
Récemment, le langage a encore subi une évolution majeure par l'introduction d'une
cinquième version. Elle standardise de nombreuses nouvelles fonctionnalités, comme
l'ajout de vidéos ou de sons dans une page. Nous étudierons cette version, même si
elle est toujours en cours de développement et de normalisation, car ses bases sont
déjà largement stabilisées. HTML5 est de plus en plus utilisé par les développeurs,
que ce soit pour les sites web ou pour les applications mobiles.
Depuis sa version 4, HTML propose deux standards de syntaxe: la syntaxe d'origine
basée sur SGML, et le XHTML basé sur le langage XML. Les différences entre les
deux sont assez succinctes. XHTML s'avère plus strict dans sa syntaxe; certains rac-
courcis ne sont pas admis. Les auteurs de ce livre sont friands de précision, voire un
peu maniaques: c'est donc ce standard d'H TML que nous allons décrire et utiliser
tout au long de ce livre.
Rentrons maintenant dans le vif du sujet par l'introduction du concept de balise qui
Vl
Q) nous amènera très rapidement à écrire notre première page web HTML et à ressentir
0L.. les premiers frissons des webmestres.
>-
U.J
N
..-!
0
N
Le concept de « balises »
@ Imaginons une page web nommée «Ma collection de chats siamois». Sans indica-
......
..c. tion, le navigateur ne peut pas savoir ce que ces mots représentent. On va donc uti-
en
ï::::
>-
a.
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
DÉFINITION Balise
Les documents HTML sont construits à l'aide de balises, que l'on nomme tags ou markups en anglais. Ces
éléments se distinguent facilement du contenu réel d'une page. Elles permettent de l'annoter et de lui
donner une sémantique.
liser des balises pour entourer le texte et signifier au navigateur qu'il s'agit du titre de
la page. En HTML, on écrira: <titl e>Ma col 1ection de chats si amoi s</titl e>.
Facile, non ?
Cet exemple nous montre que les balises HTM L sont construites à l'aide de che-
vrons < et > entourant leur nom (dans notre exemple, le nom de la balise est title).
Deuxième constat, notre texte est entouré par une balise ouvrante <ti tl e> et une
balise fermante </ti t l e> qui délimitent où commence et où finit le titre, la balise
fermante se distinguant par la barre oblique ajoutée après le premier chevron. Les
balises vont toujours par deux : une ouvrante et une fermante.
L es balises HTM L peuvent être imbriquées pour indiquer qu'un élément se trouve
dans un autre. Par exemple, si notre page contient un article, lui-même composé de
plusieurs sections, on écrira en HTM L :
<article>
La Bretagne, un pays à voir .
<section>
Introduction
Bla bla
</section>
<section>
Hi storique
Bla bla
</section>
</article>
</article>
<!-- Erreur ! Il faut refermer la balise section avant de refermer
article. -->
</section>
Figure 4-2
<article> <article>
Imbrication d'éléments
en HTML l
<section> <section>
1
<section> <section>
DÉFINITION Attribut
Les balises peuvent être enrichies d'informations diverses par l'ajout d'attributs.
Imaginons que dans notre page, nous aimerions préciser qu'un article est en français et
qu'un autre est en anglais. L'attribut 1 ang permet cet enrichissement. On écrirait alors :
<article lang="fr">
La Bretagne, un pays à voir.
</article>
<art i cle lang="en">
Brittany, a country to be seen .
</article>
Vl
SYNTAXE Attribut
Q)
,_
0 Les attributs se placent dans les balises. La valeur de l'attribut, entourée de guillemets, est séparée du
>- nom de l'attribut par un signe = (égal).
w
N
.--1
0
N Tous les attributs possibles sont définis dans le standard HTM L et vous ne pouvez
@ pas en inventer d'autres. Nous utiliserons abondamment les attributs par la suite ; ils
~
.c se révèlent souvent comme un complément indispensable de certaines balises .
Cl'I
·c
>-
0..
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
0L..
Ajoutons maintenant un titre à la page et un peu de chair au body.
>-
U.J
N
T"'f
0
N
@
.....
..c.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Nous avons maintenant notre première page HTML complète que l'on peut afficher
dans un navigateur web. Pour ce faire, recopiez ce code dans un éditeur de texte (par
exemple Notepad sous Windows). Enregistrez le fichier en lui donnant une extension
. html . Vous pouvez maintenant l'ouvrir avec votre navigateur. Il affichera le renversant
résultat de la figure suivante. Vous êtes presque prêt pour postuler chez Google !
Figure 4-3
Notre première page web ! HslXli-e de la France
(J Q fie:///C:/Documents%20and%205ettI1gs/P1erre/Mes%2 1:i ~
Vl
Q)
,_
0
>- Le titre de la page a été récupéré par le navigateur pour nommer l'onglet. L e contenu
w
N
de la balise body est affiché dans la zone principale du navigateur.
.--1
0
N
Avouons-le, la page que nous venons de créer est plutôt élémentaire. Nous allons
@ donc voir dans la section suivante d'autres balises HTML qui nous permettront de
~
.c rendre cette page un peu plus attrayante.
Cl'I
·c
>-
0..
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
L'encodage de la page
Il y a un attribut que nous avons volontairement omis d'expliquer jusqu'à présent et
qui revêt pourtant une importance cruciale. C'est l'attribut encodi ng .
Retirons-le pour voir. .. Tous les accents sont fichus ! En atteste la capture d'écran
suivante.
Figure 4-4
Notre première page web Histote de la France
C'est pourquoi tout document textuel (comme HTM L) doit être accompagné d'une
mention qui indique quel encodage est utilisé. Ainsi, le navigateur sait s'il doit afficher
une cédille ou un« o » avec umlaut s'il rencontre un octet qui vaut« 199 ». I.:encodage
sur un octet le plus souvent utilisé par les francophones est le « ISO 8859-1 » (on
inventa par la suite l'ISO 8859-15 pour ajouter, par exemple, le symbole euro).
L e prix de la mémoire a chuté, et se limiter à un octet n'a plus de raison d'être. On a
imaginé d'autres encodages qui utilisent 2, 4 voire 8 octets, permettant de repré-
senter les symboles qui foisonnent aux quatre coins du monde. Aujourd'hui, l'enco-
dage « multi-octet » le plus populaire est l'UTF-8, car il est astucieux : les
128 premiers caractères sont toujours codés sur un octet, tandis que les caractères
plus exotiques sont codés sur deux octets. Si le document ne contient que des carac-
tères élémentaires (pas d'accents), il sera affiché correctement même si le navigateur
n'est pas au courant qu'on travaille en UTF -8.
C'est ce qui donne parfois des résultats surprenants, comme dans notre exemple : notre
document est codé en UTF-8, mais le navigateur pense qu'il a affaire à de l'ISO 8859-1.
Dès lors, tous les caractères accentués sont représentés par deux caractères.
Pour conclure, lorsque vous créez un fichier HTML, il faut toujours savoir dans quel
encodage votre éditeur travaille. Nous vous conseillons évidemment de toujours tra-
vailler en UTF-8. Cela se fait via l'attribut encod i ng.
Figure 4-5
Une page web structurée La Ubre France ·Actualités
+- C 0 fie:/l/C:/Docurnents%20and%205etttlgs/Pierre/Mes"A>20 f:r ~
Dernières actualités
Actualités nationales
65% des Français sont contre les sondages
D ' après un sondage TNS Sofres Ipsos CSA lfop Médiamétrie, 65% des Français
sont contre les sondages contre 42% qui sont pour. Blah blah blah.
En '.\.1ayenne, le feu a pris ce matin dans une usine blah blah blah.
Actualités internationales
Obama favorable à une intervention en Belgique
Pour la plupart, les éléments de structuration n'ont pas de rendu visuel. L es titres
sont mis en évidence (police plus grande et grasse), mais les articles et les sections
n'ont rien pour les identifier du regard. Du moins est-ce ainsi par défaut, car à l'aide
des CSS, on pourra modifier l'apparence de tous ces éléments à notre guise.
<footer> 0
<P>© La Libre France 2012</P>
</footer>
</body>
</html>
Figure 4-6
Une page web structurée avec La Libre Franœ ·Actualités
Dernières actualités
Vl
Q)
,_
0
>-
w
N
.--1
0
Certes, le rendu n'en demeure pas moins laid (du moins d'une sobriété à la limite de
N l'austérité). Le positionnement du texte reste basique: les lignes se suivent simple-
@
~
ment alors qu'on pourrait s'attendre à ce que le contenu de la balise as i de apparaisse
.c ailleurs. Patience, la section sur CSS nous apprendra comment procéder.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure 4-7
Exemple de rendu La Libre France - Actualités
Sites p artenaires
Visiter le sjte du Monde l
Vl
Q)
,_
0
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
Les listes
HTML permet également de définir des listes. Elles peuvent être de deux types:
• soit numérotées, auquel cas on utilisera la balise <O 1> et les éléments seront
numérotés automatiquement ;
• soit à puces, auquel cas on utilisera la balise <u1> .
Les éléments de la liste sont définis à l'aide de la balise <l i> que l'on répétera autant
de fois qu'il y a d'éléments.
SYNTAXE. Liste
,_
0
>-
w Pays de diffusion du journal
N
..-1
0 • France
N
• Belgique
@ • Allemagne
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Les images
Pour insérer une image dans une page web, on passe par trois balises différentes :
• <figure> représente une « figure » au sens large. Cela peut être une image, du
code, un diagramme, etc.
• <img> représente l'image proprement dite. C'est à l'aide de son attribut src que
l'on va définir où se trouve le fichier contenant l'image. La balise <i mg> sera pla-
cée dans la balise <figure>.
Un second attribut, obligatoire, est à spécifier pour la balise : a 1t . Il ajoute un
texte alternatif (invisible) décrivant l'image au cas où elle ne s'afficherait pas. Ce
texte alternatif est également très important pour renseigner les internautes mal-
voyants (dont les navigateurs sont capables de« lire» ces textes alternatifs).
Deux autres attributs sont intéressants : wi dth et hei ght : ils précisent la hauteur
et la largeur de l'image en pixels. C'est très utile lorsque l'image est en cours de
chargement ; le navigateur sait déjà quelle place elle va prendre et peut en tenir
compte pour afficher correctement la page web.
• <fi gcapti on> précise une légende pour la figure. Cette balise, optionnelle, sera
placée dans la balise <figure>.
<figure>
<img src="adresse du fichier image"
al t ="Tex te court décrivant 7 'image" width=" 1argeur en pixe1s"
height="hauteur en pixe1s" /> 0
<figcaption> 7égende de 7'image</figcaption>
</figure>
On remarque que la balise <i mg> n'est pas fermée comme toutes celles rencontrées
jusqu'à présent O . Il s'agit d'un raccourci très utilisé : comme la balise n'a pas de con-
tenu, plutôt que d'écrire <i mg src="... "></img>, on écrira <i mg src="..." />.La balise
est dans ce cas à la fois ouvrante et fermante.
<fi gure>
<i mg src="https://www.google.be/i mages/srpr/l ogo3w.png"
alt= "îhe Google Logo" width="275" height="95" />
<figcaption>Figl. - Le Logo de Google. </figcaption>
</figure>
</body>
</html>
Figure 4-9
Exemple de rendu La Llbte Fran~ - Ac:tu.!lltés
Partenaires
,_
0
1
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure 4-10
Exemple de rendu de texte La Libt~ Franœ • A~liœs
Les formulaires
L'objectif de ce livre est de vous apprendre à réaliser des sites web dynamiques, en
d'autres mots, des sites web dont les pages sont créées dynamiquement par un ser-
veur web.
Une des grandes forces du Web dynamique est la possibilité de passer à une page web
des paramètres, souvent renseignés par l'utilisateur lui-même.
Par exemple, sur la page de recherche de Google, nous avons un champ de recherche. Lorsque l'utilisa-
teur entre la requête « Solvay » dans ce champ et clique sur le bouton Recherche Google, l'URL suivante
est appelée :
~ http://www.google.be/search ?q=Solvay
Cette adresse n'est pas fictive, vous pouvez l'essayer dans votre navigateur. Plus précisément, c'est la
page web search qui est appelée avec un paramètre nommé q et dont la valeur est So 1vay.
Nous allons étudier comment insérer dans une page web des zones de texte et des
boutons pour communiquer ce type d'information.
En termes HTM L, on parle de «formulaires» lorsqu'il s'agit de récolter des infor-
mations auprès de l'utilisateur pour les transmettre en paramètre. Un formulaire peut
contenir des zones de saisie de texte, des cases à cocher, des listes de choix, des bou-
tons radio, etc. Chaque formulaire doit contenir un bouton de soumission.
Il s'agit d'un bouton qui, une fois pressé, appelle une URL, lui transmettant en paramètres tous les
champs du formulaire.
0L.. • <input> représente un champ. Son attribut type permet de définir la forme que
>-
U.J
prendra le champ. Pour une zone de saisie, on utilisera le type text, pour le bou-
N ton de soumission, on utilisera le type s ubmi t .
..-!
0
N Voici le code HTML de notre formulaire.
@
......
..c.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Figure 4-11
Exemple de rendu - Google
d'un formulaire dans +- -t C 0 fle:///C:/Documents%2 0and%2 0 5etmgs/Pierre/Mes<>A>2 0 1:r ~D
une page web
Lorsqu'on clique sur le bouton Rechercher, la page suivante est appelée. On constate
que l'URL construite est bien celle attendue.
Figure 4-12
Page appelée lors
de la soumission
du formulaire
•
.-
1
1 solvay - Redlerche Google
+Pierre
c
Recherche
-
a https: f[www.google.be/search?q=Solvay
Images E mali Documents AgPnda Groupes Contacts Maps
- I Cl 1 X
Plus~
1
Go gle Solvay
Maintenant que nous avons appris les bases de HTML et que nous sommes capables
de créer une page web, il est temps de passer à l'étape suivante, à savoir la mise en
forme de la page à l'aide des CSS.
ÀLIRE
ill Rodolphe Rimelé, HTMLS - Une référence pour le développeur web, Eyrolles 2011
CSS signifie Cascading Style Sheets (en français, «feuilles de styles en cascade»).
Analysons plus en détail ce sigle :
• « Feuilles de styles » désigne simplement le fait que CSS permet de « styler » une
page web et que son code, bien séparé du HTML, est placé dans des« feuilles».
• « En cascade» désigne la possibilité de définir à plusieurs endroits des styles s'appli-
quant à un même élément. Des règles de priorité se chargent de départager ces ins-
tructions de styles afin de savoir lesquelles il faut réellement appliquer à l'élément.
Analysons maintenant deux principes de base des CSS : les propriétés et les sélec-
tions d'éléments.
On définit d'abord un sélecteur. Ensuite, entres accolades, on insère toutes les pro-
priétés CSS que l'on désire appliquer aux objets sélectionnés.
p {
bac kground - color : red ;
}
Un id ne doit évidemment être attribué qu'à un seul élément, sous peine d'ambiguïté.
Par ailleurs, il ne doit pas être confondu avec l'attribut name que l'on retrouve dans les formula ires et
que nous découvrirons par la suite.
Vl
Q)
Ensuite, en CSS, pour sélectionner précisement cet élément :
0L..
>-
UJ EXEMPLE 4.15 Fond rouge pour la liste« listeDesPays,,
N
.-f
0 ul#listeDesPays {
N
@ bac kground- color : red ;
...... }
..c
en
ï::::
>-
a. Le sélecteur est alors agrémenté du signe dièse suivi de l' i d de l'élément.
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
li . francophone {
background - color: blue ;
}
L e sélecteur est alors agrémenté d'un point suivi de la classe à cibler. Dans notre
exemple, Belgique et France auront un fond bleu car tous deux sont « au moins » de
classe « francophone».
Appliquer une propriété seulement quand lélément est dans un état donné
On peut également appliquer un ensemble de propriétés à un élément lorsqu'il est
Vl
Q) dans un certain état. Le sélecteur est alors agrémenté de deux-points suivi de l'état à
0L.. cibler. Exemple courant, imaginons que l'on veuille colorer en rouge les liens hyper-
>-
UJ textes au survol de la souris. On écrira en CSS :
N
.--!
0
N
EXEMPLE 4.19 Liens en rouge au survol de la souris
@
...... a:hover {
..c color : red ;
en
ï:::: }
>-
a.
0
u
Apprendre la programmation web avec Python et Django
<Ul id="listeDesPays">
<li class="francophone neerlandophone">Belgique</ li>
<li class="francophone">France</li>
<li class="germanophone">Al l emagne</li>
</u l>
<ul id="listeDesPresidents">
<li class="francophone">François Hollande</li>
<li class="ang l ophone">Barak Obama</ li>
<li class="francophone">Joseph Kabila</li>
</U l >
Ici, les mêmes classes ont été appliquées à deux listes différentes. Si l'on veut mettre en
bleu les pays francophones mais pas les présidents francophones, on écrira en CSS :
ul#listeDesPays li . francophone {
background - color : blue ;
}
L e sélecteur dans ce cas signifie « tous les éléments 1 i qui ont la classe francophone
et qui se trouvent dans un élément ul d'i dl i steDesPays ».
Vl
Q)
Si l'on veut appliquer un même ensemble de propriétés à plusieurs sélecteurs, il faut
0L..
séparer ces derniers par des virgules. Le code suivant:
>-
UJ
N
.-f
EXEMPLE 4.22 Fond bleu pour les francophones et les anglophones
0
N
@ li.francophone, li.anglophone {
...... background-color: blue;
..c }
en
ï::::
>-
a.
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
est équivalent à:
EXEMPLE 4.23 Exemple. Fond bleu pour les francophones et les anglophones
li . francophone {
background - color : blue ;
}
li .angl ophone {
backgro und- color : blue;
}
a#lienVersGoogle:hover {
col or : red ;
}
Ce sélecteur signifie« lorsque l'élément a dont l'i d est 1 i enVersGoogl e est survolé».
EXEMPLE 4.25 Fond rouge pour tous (très laid, on vous l'accorde)
~' {
backgro und- color: red ;
}
D'autres sélecteurs existent encore, mais ils sont moins utilisés, car ils ne sont pas pris
en charge par tous les navigateurs.
0L.. instructions CSS. Reste à savoir où placer ce code. Plusieurs possibilités s'offrent à vous.
>-
UJ
N Placer le code CSS dans les balises HTML
..-!
0
N Une première (mauvaise) possibilité consiste à placer directement des règles CSS au
@ niveau des éléments H TML, à l'aide de l'attribut style. C'est ce qu'on appelle du
.....
..c CSS inline.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Cette méthode est fortement déconseillée, car on perd tout l'avantage de la sépara-
tion du contenu et de la forme.
Figure 4-13
Notre premier CSS ! ._ La Libre Franœ • Actua~tés
Liste de pays
•
•
• Allemagne
C'est votre première CSS, mais par la suite vous n'aurez de CeSSe de recourir à cette
pratique !
ul #l i steDesPays l i.francophone {
background- color: blue ;
}
La meilleure solution reste de placer son CSS dans un fich ier séparé. Ainsi, gra-
phistes et développeurs peuvent travailler en totale indépendance les uns des autres,
et le fichier CSS peut être utilisé pour plusieurs pages différentes.
D ans les sections suivantes, nous allons nous attarder sur quelques propriétés et con-
cepts CSS bien utiles et pas toujours évidents à comprendre.
Figure 4-14
Le modèle de « boîte » CSS Margin (40px)
Padding (30px)
'
Contenu de la boîte
Taille totale
(240px)
'
Marges extérieures (appelées margi n en anglais), marges intérieures (paddi ng), bor-
dures (border), hauteurs (hei ght) et largeurs (wi dth) peuvent être modifiées à notre
Vl
Q) guise via des propriétés CSS ad hoc. Pour l'élément représenté sur la figure, on aura
,_
0 le CSS suivant (on imagine que l'élément est un paragraphe) :
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
p {
margin : 40px;
padding : 30px
height : 60px;
border : 20px solid black ;
width : 100%; 0
}
À la lecture de ce code, on constate qu'on a défini une hauteur fixe en pixels. La lar-
geur, en revanche, a été définie comme étant égale à 100 % 0 , ce qui signifie que la
boîte va prendre toute la place disponible en largeur.
Chaque élément possède des valeurs par défaut pour ces différentes propriétés CSS.
Par exemple, les paragraphes ont par défaut une marge verticale permettant de les
espacer les uns des autres.
Modifier ces valeurs donne toute liberté pour modifier l'aspect des pages web. Nous
verrons par la suite un exemple plus complet illustrant un usage judicieux de ces pro-
priétés.
Figure 4-15
<body>
Imbrication de « boîtes »
en CSS
<article>
<hl>
1
<p>
Vl
l
Q)
<a> <a>
,_
0
1
11
>-
w
N
..-1 <p>
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Vl
Figure 4-16
Positionnement en CSS +-
Positionnement en CSS
C 0 - - 0
file:///C:/DOcuments%20and%205ettir -t1
Positionnement en CSS
X
'°
Q)
,_
0 Paragraphe l
>-
w Pilfagraphe ~
N
.--1 Paragraphe 3
0
N Parngraphe 4
@
~
.c
Cl'I
·c
>-
0..
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
On voit clairement que les paragraphes prennent toute la largeur de la fenêtre (si on
exclut les marges) et que les liens hypertextes prennent juste la largeur de leur texte.
Lorsque des éléments frères sont positionnés en se suivant «l'un après l'autre», on
dira qu'ils suivent le «flux courant».
Il est important de noter que seuls les éléments de type b1ock peuvent voir leurs
dimensions modifiées à l'aide des propriétés margi n, wi dth et hei ght .
Q PœibOmement en css
- 1-
Positionnement en CSS
10 1 X
- 1_
C ~ fie:///C:/Oocuments0/o20and%20Setti 'Cr ~D
Positionnement en CSS
10 1 X
Paragraph~ l · Lorem tpstun dolor s1t ami:t. consectetui Pai agraphe 1 - l..orem 1pstu11 dolor sit amel .:onse.:tetur
.adtp1scu1g eht Fusce ahquet magna qws 1psw11 preb.wn ut cli:tum adtpm:mg eht Fus ce ahquet magna qUls 1pswn pretnun ut ch :tum
pum; uU;im.:orper purus ullam.oorper
D ans cet exemple, nous avons sorti le paragraphe 2 du flux. C'est triste pour ses
frères, mais c'est comme s'il n'existait plus : le paragraphe 3 vient se placer après le
paragraphe 1. Il est intéressant de noter également qu'après être sorti du flux, le
paragraphe 2 a pris, par défaut, la largeur de son contenu.
Vl
Q) La sortie du flux se fait via la propriété CSS pos i tion, qui peut prendre plusieurs
,_
0 valeurs, en fonction de ce que l'on désire :
>-
w • stati c : valeur par défaut de la propriété. Indique que l'élément doit rester dans
N
.-1 le flux .
0
N • re 1a ti ve : ne sort pas l'élément du flux, mais permet de décaler sa position par
@
~
rapport à celle qu'il aurait dans le flux. Pour effectuer un décalage, on utilise les
.c propriétés top, 1eft, ri ght et bottom.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
• abso l ute : sort l'élément du flux. O n peut également utiliser les propriétés CSS
top, l eft, ri ght et bottom pour définir le positionnement de l'élément, lequel se
fera par rapport au premier élément parent qui a une position autre que statique.
S'il n'y en a aucun, ce sera par rapport à l'élément racine html (en d'autres mots,
par rapport au début de la page web).
L a figure suivante illustre les positions relatives et absolues.
- 1_
C ~ fie:///C:/Oocuments%20and%20Settl 'Cl ~
10 1 X
Pesitlonnetn!nt en CSS
Paragrapho 1 - Lorem 1pstun dolor stt amel come-:tetur Paragraphe l - Lorem 1pstun clolor sit amel consectettu
ad.'P!!<culg eht Fusce ahquel magna qtus tpsum preurnn ut ch·:ttuu ad!p1scutg eht Fusce ahquet magna qms tpnun pt euum ut d!·:Uun
urus ullamcorpcr , .......... 11 .......... ,................
?rtrngr ;lrh..
Paragraphe 3 - Lorem 1psmn dolor stt runet •:onsectetur
chp1Scnig eht fus•:e ahquet magna qws 1psum preUmn ut ch:tmn
urus ullam.:orpe-r Paragraphe 3 - Lorem 1pnuu dolor s1t am~t. Gonsecteh1r
achp1scu1g ~ht Fusce ahquet magna qtus 1pstun preumu ut ch·:tlun
urus ullamcoruet
>I
D ans l'exemple de gauche, le paragraphe 2 a été mis en position abso lute avec top et
l eft à 0 à l'aide du code suivant :
p#p2 {
pos i t i on: absolu te ;
top : O;
left : O;
}
p#p2 {
position: relative;
top: - 25px;
left: lûpx;
}
Résultat, le paragraphe a été décalé par rapport à sa position initiale dans le flux : de
25 pixels vers le haut et de 10 pixels vers la droite. Ce décalage ne modifie en rien la
position du paragraphe frère suivant (le paragraphe 3) qui agit comme si le
paragraphe 2 était à sa position initiale dans le flux.
Figure 4-19 .
Maquette de notre page web
d'exemple ©l@ hneJtwww,ex<mffc.co•• 1 Pl
En-tête
Vl
Q)
,_
0
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Pour mieux comprendre, nous avons coloré chacun des éléments à l'aide de cette
CSS, dont les instructions sont placées dans l'en-tête de la page :
Q)
aside#menu2 {
Ceci est le menu 2
,_
0 background- col or : yellow;
>-
w }
section#contenu { Contenu
N
..-1
0 background - color : blue; C' - -1 -et le -ont-nu
N }
1
@ </st yle>
~
.c </head> Figure 4-20 Première ébauche de notre page web
Cl'I
·c
>-
0..
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
On constate, et c'est normal, que tous les éléments se suivent les uns après les autres
puisque, par défaut, ils font tous partie du flux courant.
Essayons maintenant de placer le premier menu à gauche et le deuxième menu à droite.
Pour ce faire, on va les sortir du flux en leur attribuant une position absolue. Profitons-
en pour leur donner leur largeur fixe. Nous ajoutons les instructions CSS suivantes :
aside#menu2 {
background - color: yel low;
right: O;
Figure 4-21 Placement des menus
}
On aimerait maintenant que les menus se trouvent sous la banni ère ; il suffit de les
déplacer vers le bas à l'aide de la propriété top. D e même, on aimerait que la ban-
nière ait une hauteur fixe de 50 pixels et qu'elle soit« collée» aux bords de la page;
nous allons pour cela passer cet élément en position absolue. Lorsqu'il s'agit de tou-
cher à des propriétés telles que hauteur et position, il est souvent plus facile de tra-
vailler en position absolue, afin de ne pas subir des effets de bords dus au positionne-
ment automatique dans le flux courant. Nous allons donc écrire le code suivant:
header#enTete {
background - color: red;
height : SOpx;
Vl
Q)
positi on: absol ute; «t
top: O; f)
,_
0
left: O; Q
>-
w width: 100%; 0
N }
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
aside#menul, as i de#menu2 {
top: SOpx;
width : 80px;
position: absolute ;
}
Grâce à ce code, nous sortons le header du flux courant 0 , nous le plaçons tout en
haut 8 à gauche 9 et lui demandons de prendre la totalité de la largeur 0 - L e rendu
est visible sur la figure suivante.
Figure 4-22
Positionnement de l'en-tête
Il reste un tout dernier problème à régler. Le contenu se trouve derrière les boîtes que
nous avons placées en position absolue. Un moyen simple de résoudre ce problème
consiste à ajouter des marges extérieures à la boîte de contenu : plus précisément, une
marge en haut de taille égale à la hauteur de l'en-tête, et des marges à droite et à
gauche de taille égale à la largeur des menus. Afin de ne pas« coller» la boîte de con-
tenu aux boîtes qui l'entourent, nous allons augmenter ces trois marges de 10 pixels.
Nous allons donc écrire le code suivant:
Vl
Q)
margin - right: 90px ;
}
,_
0
>-
w
N
..-1
0
Contenu
N
C• i -et J, onknu
@
~
.c
Cl'I
·c
>-
0.. Figure 4-23 Décalage du contenu
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
Chose étrange : la boîte de contenu n'est certes pas collée à ses boîtes adjacentes,
mais l'espace à droite et à gauche est plus important que celui d'en haut! Pourtant,
nous avons ajouté exactement 10 pixels à chacune des trois marges ... L'explication
est simple : le body possède lui aussi des marges qu'il va falloir annuler (si vous
reprenez les premiers exemples, vous verrez que les boîtes du flux ne sont pas collées
au bord de la page). Pour annuler les marges du body, on va écrire le code suivant:
body {
margin : O;
padding: O;
}
Figure 4-24
Ajustement du décalage
du contenu
Nous terminons ici notre tour d'horizon des CSS. Nous avons volontairement omis
de vous parler en détail de toutes les propriétés possibles, car elles sont pour la plu-
part triviales à utiliser. Il était préférable de se focaliser sur les quelques concepts dif-
ficiles à comprendre et à maîtriser.
Les événements
Le DHTML se base sur la notion d'lvénements. HTML prévoit en effet une série
d'événements associés à ses éléments. Par exemple :
• click : se produit lorsqu'on clique sur un élément.
• db 1c1 i ck : se produit lorsqu'on double-clique sur un élément.
• mouseover : se produit lorsqu'on passe la souris sur un élément.
• change : se produit lorsque la valeur d'un champ de formulaire change.
C'est à ces événements que l'on va réagir via du code qui changera l'aspect et le con-
tenu de la page.
Script qui a rencontré les faveurs d'un plus grand nombre de développeurs, notamment
car il est compatible avec tous les navigateurs.
Pour l'essentiel, ce livre se concentre sur un dynamisme qui se déploie côté serveur,
mais nous retrouverons JavaScript en appoint de Django dans le dernier chapitre,
lorsqu'il sera question de répartir un peu d'interactivité aussi du côté client. Il est en
effet capital d'ores et déjà de noter que ces langages de scripts s'exécutent côté client,
c'est-à-dire dans le navigateur et non dans le serveur.
La syntaxe de JavaScript est proche de celle de Java, mais plus simple (n'allez jamais
dire cela à un programmeur Java susceptible!). Nous n'allons pas étudier en détail cette
syntaxe, les exemples que nous vous proposerons seront suffisants pour comprendre.
Figure 4-25
Un article composé de deux Mapag!! wl!b
Notez que, comme cible pour le lien, nous avons mis # Q . Cela permet de rester sur
la page lorsqu'on clique sur le lien.
Afin que le deuxième paragraphe soit par défaut invisible, nous allons ajouter le code
CSS suivant :
p#articleComplet {
display : none ;
}
L e code est placé dans l'attribut oncl i ck de l'élément a. Il se déclenchera lors du clic
sur le lien.
L e code peut aussi être placé dans une balise <script> située dans l'en-tête du docu-
ment. Dans ce cas, il devra être écrit dans une fonction, qui sera appelée dans l'événe-
ment oncl i ck :
<head>
<Script type="text/javascript" src="monJavaScript.js"></script>
</head>
Vl
jQuery et les frameworks JavaScript
Q)
/* Méthode standard */
document.getElementByid(ID)
/* Internet Explorer */
document.all(ID)
F Nets cape ~, /
eval ( ' document.' +ID)
Il n'était donc pas rare de voir du code ressemblant à « If Internet Explorer Alors, If
Firefox Alors, etc. ».
Afin de faciliter la vie des développeurs, sont apparus des frameworks JavaScript dont
l'objectif était de cacher cette complexité. Le framework offrait alors ses propres
fonctions, lesquelles se chargeaient d'écrire le bon code pour le bon navigateur.
Le rôle de ces frameworks s'est très vite étendu pour compiler et offrir des fonctions
nouvelles souvent utilisées par les développeurs.
Aujourd'hui, un des frameworks les plus connus et utilisés est jO!iery. Il permet entre
autres de :
• simplifier et enrichir l'accès aux éléments de la page;
• simplifier et enrichir la gestion des événements ;
• appliquer des effets et des animations sur les éléments d'une page web ;
• simplifier l'application de styles à des éléments.
Écrit en JavaScript, jO!iery est donc devenu le framework de DHTML par excellence.
Concrètement, jO!iery se présente sous la forme d'un fichier JavaScript comprenant une
série de fonctions. Ce fichier est téléchargeable sur le site officiel du framework. Une
fois téléchargé, pour l'utiliser, il suffit de l'inclure dans l'en-tête du fichier H TML:
<head>
<Scr i pt t ype=" text / j avascr i pt" src="j qu e ry- 1.7.2 . min .j s "></script >
Vl
</h ead>
Q)
0L..
>- Une fois le framework inclus, celui-ci s'utilise notamment via la fonction $,qui sélec-
UJ
N
tionne des éléments de la page web :
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Rappels sur HTMLS, CSS et JavaScript
CHAPITRE 4
On le voit, la sélection d'élément s'opère de la même manière que dans les CSS.
Une fois les éléments sélectionnés, on peut les manipuler:
De nombreuses autres possibilités sont offertes par jQyery. Nous ne les relaterons pas
ici, l'objectif étant de vous offrir juste un petit aperçu de cette technologie et de son
rôle dans le cadre du développement web.
ÀLIRE jQuery
Si vous désirez en apprendre plus sur jQuery :
ill Éric Sarrion, jQuery 1.7 et jQuery U/, 2e édition, Eyrolles, 2012
0L..
>-
U.J
N
T"'f
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
5
Mise en application :
un site web inspiré de Facebook
Ce chapitre présente le projet de développement qui servira de base pour tous les autres chapitres :
Trombinoscoop. Tout projet web démarre par la rédaction de ses cas d'utilisation {use cases) et la
conception de ses wireframes, et d'une base de données relationnelle côté serveur. Quelques rappels
théoriques sur le modèle relationnel se révèlent indispensables. Django exige que le modèle de données
soit réalisé via un diagramme de classes, donc dans une perspective purement orientée objet. Par
conséquent, quelques lignes sont consacrées à l'épineux problème de la mise en correspondance entre le
modèle relationnel et le modèle objet.
Vl
Q)
0L.. SOMMAIRE
>-
UJ
~ Trombinoscoop : le projet auquel ce livre va se consacrer
N
..-!
0 ~ Cas d'utilisation et maquettage (wireframes)
N
@ ~ Rappels théoriques sur les bases de données relationnelles et différence avec la modélisation orientée objet
......
..c ~ Diagramme de classes de Trombinoscoop
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Ce chapitre décrit le projet de site web que nous réaliserons à partir de Django. Son
développement sera exposé sous forme de tutoriel qui servira de fil conducteur à
l'apprentissage du framework Django. Il sera construit progressivement, à mesure
que de nouvelles notions seront introduites. Il permettra de comprendre par la pra-
tique et concrètement chaque aspect du framework.
Comme pour tout projet de développement informatique, nous allons également
passer par une phase préalable d'analyse. Décrire brièvement les fonctionnalités que
l'on désire voir sur le site web ne suffit pas. Avant d'écrire la moindre ligne de code, il
est important de se poser un instant, prendre un peu de recul, réfléchir à ce que l'on
va réellement développer et à certains éléments de structure du code.
C'est pourquoi ce chapitre se propose également de vous exposer brièvement quel-
ques méthodes d'analyse. Rassurez-vous, cet exposé sera plus que sommaire, à mille
lieues de la complexité que l'on trouve parfois dans certains projets réels. Nous allons
nous limiter à décrire et exploiter au plus pressé trois éléments d'analyse:
• Les use cases du site web (ou en français« cas d'utilisation») entrevus dans le cha-
pitre deux. Ils décrivent sommairement les fonctionnalités principales du site et
délimitent l'étendue du projet. À quoi va bien pouvoir servir ce site?
• Les wireframes du site web, plus en rapport avec la conception graphique. En
d'autres mots, on va décrire les différents écrans du site web et leur enchaînement
(« lorsque je clique sur tel bouton, j'arrive sur tel écran »).
• Le modèle objet de la base de données. Il est en effet déjà utile à ce stade de réflé-
chir sur les données que l'on voudra sauvegarder et traiter dans notre site web.
Les use cases, les wireframes et le modèle objet ne doivent pas être figés : ils peuvent être
modifiés et évoluer au gré des développements.
0L.. En découvrant ce carnet web un peu statique, Marc Van Saltberg, étudiant en infor-
>-
UJ matique de l'Université, eut une idée géniale pour le rendre plus personnel et plus
N
.-f vivant : pourquoi ne pas créer un site web où chaque personne gèrerait elle-même
0
N son profil, pourrait indiquer quels sont ses amis et publier des messages (à destina-
@ tion de tous ou uniquement de ses amis).
......
..c
en
ï::::
>-
a.
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
Une fois développé, le site de Marc connut un tel succès qu'il décida de le rendre dis-
ponible à d'autres universités, puis également au monde non universitaire. On con-
naît la suite de cette fameuse histoire belge : le succès du site fut planétaire et, quel-
ques années après, il comptait des millions d'utilisateurs (ce qui permit à Marc de
créer une entreprise florissante, qu'il décida même de coter en Bourse avec une valo-
risation de plusieurs milliards d'euros) .
Oui, c'est bien l'histoire de Facebook que nous venons de vous conter. Nous avons juste changé les noms
de personnes et de lieux ...
C'est ce site web, dans sa première version basique et élémentaire, que nous allons
réaliser dans les chapitres suivants. Avant toute chose, Marc, tout geek qu'il est, a dû
procéder à un peu d'analyse.
Il s'agit de diagrammes très simples, reprenant simplement un intitulé court pour chacune des fonction-
nalités et une ligne vers un utilisateur pour indiquer qui va faire usage de cette fonction.
La figure 5.1, page suivante, expose les différents objectifs de notre projet Trombi-
noscoop.
Nous avons identifié neuf use cases, tous utilisés exclusivement par un même acteur
que l'on dénommera simplement l'internaute.
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Figure 5-1
Cas d'utilisation Trombinoscoop
de Trombinoscoop
Vl
Q)
Maquette du site : les wireframes
,_
0
I.:aspect du site et sa navigabilité peuvent s'élaborer assez tôt en identifiant l'organisation
>-
w visuelle et le mode d'emploi de chaque page. Il faut s'interroger sur les informations
N
.--1
0
accessibles sur les pages, ainsi que sur les fonctionnalités rendues disponibles pour cha-
N cune d'entre elles. D es priorités tant entre ces informations qu'entre ces fonctionnalités
@
~
devront être établies. Pour cela, il est souhaitable d'envisager certains scénarios d'utilisa-
.c tion pour concevoir et tester au mieux l'aspect et le mode d'utilisation de la page.
Cl'I
·c
>-
0..
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
DÉFINITION Wireframes
Il s'agit de dessins grossiers représentant sommairement chacun des écrans du futur site web. Les wire-
frames doivent permettre au premier coup d'œil de se faire une idée du contenu et des fonctionnalités de
chaque page, ainsi que des liens qui les unissent.
Pour imaginer les écrans de Trombinoscoop, il faut partir des cas d'utilisation que
nous venons de définir. Tous nos cas doivent être couverts. Attention : plusieurs
écrans seront parfois nécessaires pour un seul cas d'utilisation et, inversement, un
écran peut très bien proposer plusieurs cas d'utilisation.
Pour imaginer les écrans, il n'est malheureusement pas de recette miracle. Seules
l'imagination, l'inspiration et l'expérience vous amèneront à un résultat probant.
Pour Trombinoscoop, nous sommes arrivés à la définition de six écrans :
• I...:écran d'authentification est le premier écran à apparaître lorsqu'on arrive sur le site.
• Un écran sert à se créer un compte si l'on n'en possède pas encore.
• I...:écran d'accueil est l'écran principal du site. Il affiche un résumé du profù de l'utili-
sateur connecté, les messages publiés par ses amis et la liste de ses amis. C'est à partir
de cet écran que l'utilisateur pourra publier de nouveaux messages. Cet écran offre
également des liens permettant d'ajouter un ami, consulter ou modifier son profù.
• Un écran sert à l'utilisateur pour modifier son profil.
• Un écran affiche le profil de l'utilisateur.
• Un écran composé d'un seul champ permet d'ajouter quelqu'un à sa liste d'amis
sur la base de son courriel.
Une fois ces écrans imaginés, il reste à les coucher sur papier sous forme de wire-
frames. Un crayon et un papier suffisent amplement. Il n'est nul besoin d'utiliser des
logiciels graphiques complexes ou d'être un graphiste hors pair: un assemblage pri-
mitif de carrés et de rectangles devrait faire l'affaire.
Vl
Q) L'écran d'authentification
0L..
>- Cet écran est le premier qui s'affiche lorsqu'on arrive sur le site web Trombinoscoop. Il
U.J
N
contient simplement un formulaire de login et un lien vers la page de création de
T"'f
0 compte pour les visiteurs qui ne possèderaient pas encore de compte (voir figure 5-2).
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
L'écran d'accueil
Il s'agit de l'écran principal du site. Il reprend dans l'en-tête un bref résumé du profil
de l'utilisateur, au centre l'ensemble des messages des amis, et dans la colonne de
droite la liste des amis.
On voit clairement que cet écran réalise plusieurs cas d'utilisation à la fois ; il s'agit
d'un exemple parfait de non- bijectivité entre « cas d'utilisation » et « écran » (voir
figure 5-4).
Vl
Q)
0L..
>-
UJ
N
.--!
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
Figure 5-2
Wireframe de lécran
ht1p ·//www, tromt11no~p.com
Pl d'authentification
1
Courriel : [email protected].
,.
.-1
0
N d'un compte
@
~
.c Vt.rs lopogt.
Cl'I d'auihentificotion
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Vers Io page
Figure 5-3 d'affichage d'un
Wireframe de l'écran d'accueil profil
·~
©@ h11p //www.tromb1110S<oop.<om
1 I?I
~
Vers Io page de
Pierre Alexis ( Voir le profd } ( Modifier le profil }- .__,• modif1C(Jt/on du
Étildiont en dewdème du Master en mothémot oque profil
Mes amis
Publier un message: \;rel risolu l'hypot~e de Riuncnn 1 11 Publier )
Gag! Rabier dot :
Ce site est géniol 1
[ Ajouter )- _ ,...,.. Vers Io page
d'cl)ou1 d'un omi
~c1Bgl2îcc
t:llllllll~
l!w•ol dit : Hugues k~ioi
Incroyable ce site 1 .wiri~~ot Vers Io page
M!!!::tin C111!12i~
• d'oHlchoge d'un
profil
©@ http•//www.tromb"ios.:oop.com
1 Pl
l>ogoCI
Modification de mon profil
Nom : !Alexis 1
Pré.nom : Pierre 1
l
Dote de naissance : 14/08/1902
Motricule : 101030405
Courriel : \[email protected] 1
Télépnone füce : !oz 756 89 06
Til~hone mobile : l0495 67 89 40
faculté : 1Sciences 1• ]
Mot de passe , 1· •.. .. .. 1
Vl
Q) ~$ ou1res t:homps SOflt 1 Cursus : \ Mllstcr en rnathémotiques
offich& dclls le cos dun
,_
0 Figure 5-5 employé Année : \Ceuxi~me l•J
>-
w Wireframe de l'écran Modifier
N de modification du profil
.--1
0
N
@
?
~
.c Retour è Io page
OI d'OC<:ueîl
·c
>-
0..
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
Figure 5-4
Wireframe de lécran
©J (2) http~//w•wtroffttM'IOSCOOp.com
1 S!I d'affichage d'un profil
l~CI
-
Affichage d'un prof il
Nom : Alvcis
l'réllom : Pierre
Dote de noisS<111Ce : 14/08/1902
Mll tn~ul e : 01030405
CoumeJ: [email protected]
Téléphone fixe : 02 756 8906
Tiliphone mobile : 0495 67 8940
FOGlllté : Sciences
{ ~tour )
...
Ret0<ràlopoge
d'accueil
·-
© @ htrp //_.. tromb<noKO<>p.com
1 I.51
l>ogoCI
Ajoute r un ami
Jr
@@~ I Pl © @ -.;;;;;;;;;;;- 1 Pl
-
Sl pas dt
..... GOITlptt
Création de ,
Log in
compte SI créotion
ok ...,,,..
Si loginok
·~
Si voir mon
•
,,.
profil"" uJui
d'un ami
Si ctjCKlter Si ~tour
Si ajout ok un ami
~ ,
@@~ I Pl
©@ ....,_ .. 1 Pl
Vl
Q)
Visualisation d'un
,_
0 Figure 5-5 pr ofil
>-
w Encha'rnements des écrans Ajout d'un ami
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
en fixant les valeurs d'attributs pour un cas donné, et qui donnerait naissance à un
objet dans le cas de la classe, donne ici naissance à un enregistrement. Nous parlerons
des différences essentielles que présentent tables et classes dans la suite du chapitre.
• Une deuxième raison est l'existence d'un mode d'organisation de ces tables, dit
relationnel, dont la qualité première est d'éviter d'avoir à reproduire la même
information plusieurs fois. On imagine aisément tous les problèmes liés à la
duplication des informations : mises à jour plus pénibles et erreurs d'encodage
plus probables. Chaque table se doit de coder un et un seul concept donné, et il
est nécessaire de séparer l'encodage des informations dans des tables distinctes
mais conservant toutefois des relations qui permettent, à partir de l'une d'entre
elles, de retrouver les informations de l'autre.
nom
prenom
fonction
adresse_courriel
no_telephone
FKl id_service
Le premier attribut de la table, et le plus important, est appelé la clé primaire. Tout
employé de l'Université libre de Bruxelles possède un matricule qui permet de l'iden-
tifier. On conçoit l'existence d'un tel attribut dans une base de données. Ni le nom,
ni le prénom, ni l'adresse, ni l'âge ne permettrait l'accès unique à un employé donné.
C'est par l'attribut clé primaire que l'on parvient à tous les enregistrements désirés et
eux seuls. Le système de gestion de la base de données sait, à partir d'une valeur
donnée unique de cet attribut, retrouver l'enregistrement unique qui lui correspond.
Aucun membre de notre université ne partage son matricule avec un autre.
Chaque employé de l'université fait partie d'un service. Chaque service est composé
d'un nombre important d'employés et se caractérise lui-même par un ensemble d'attri-
buts qui lui sont propres : la dénomination du service, le nombre de ses employés, sa
location géographique (son campus), la faculté à laquelle il appartient, etc.
Vl
EN PRATIQUE Pas de duplication d'information
Q)
,_
0 Bien sûr; il serait théoriquement nécessaire d'ajouter toutes les informations du service qui l'héberge
>-
w
pour chaque employé, mais on conçoit bien le ridicule qu'il y a à répéter ces mêmes informations pour
N tous les employés d'un même service. Et c'est sans compter les multiples sources d'erreurs que la répéti-
.--1
0 tion de ces mêmes informations risque de causer. Rappelez-vous la doctrine première de tout informati-
N cien qui se respecte : séparer les informations, de manière à ce que l'on puisse affecter une partie de cel-
@ les-ci sans en affecter une autre. Il serait stupide, si le service venait à déménager ou à changer de nom,
~
.c qu'il faille répercuter ce changement sur tous les employés de ce service.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
La solution, illustrée dans la figure qui suit, est de recourir à une autre table pour y
stocker ce qui ne concerne que les services et d'établir une relation « 1-n » avec la
table Emp l oye (un employé appartient à 1 service et chaque service englobe
n employés). Dans le modèle dit «relationnel», les informations à stocker sont
regroupées selon leur nature dans des tables mises en relation par un mécanisme de
jointure de clés : de la clé primaire (PK sur la figure, ou Primary Key) à la clé étran-
gère (FK ou Foreign Key).
Figure 5-7
Tables « Employé » Service Employe
et « Service »
PK id ~~rvi~~ - PK id mS!tri~yl~
nom nom
adresse prenom
t elephone fonction
nbreEmployes adresse_courriel
FKl id_ campus no_telephone
FK2 id_faculte FKl id_service
Ainsi, un des attributs de l'employé est la clé étrangère du service qui ne peut prendre
que les seules valeurs prises par la clé primaire de ces mêmes services. Pour obtenir
les informations du service à partir de l'employé, il suffit de connaître la valeur de sa
clé étrangère et de se référer à la table Servi ce . De la sorte, chaque service n'apparaît
plus qu'une seule fois même s'il est partagé par de nombreux employés. C'est le lien
(qui apparaît dans le graphique) entre la clé primaire d'une table et la clé étrangère de
l'autre qui indique, pour chaque enregistrement de la deuxième table (chaque
employé), quel est son correspondant unique dans la première (son unique service).
Relation 1-1
Même si cette « division du travail » coule de source dans le cas d'une relation « 1-n »
entre les deux tables, une semblable division peut également résulter d'une relation
« 1-1 » entre deux tables. Ainsi imaginons que chaque employé occupe un seul
Vl
bureau et qu'un bureau, lorsqu'il est occupé, ne l'est que par un seul employé. Bien
Q)
qu'il s'agisse d'une relation« 1-1 »,garder séparées les deux tables et les informations
,_
0
>- qu'elles contiennent témoigne d'une bonne pratique de conception. En effet, les
w
N
notions de bureau et d'employé restent bien distinctes et il est logique de séparer les
.--1
0 informations relatives à l'un et à l'autre .
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
A priori, la clé étrangère pourrait cette fois se trouver dans l'une ou l'autre des deux
tables. C'est la nature du problème qui choisira l'emplacement à privilégier. On peut
imaginer que, s'il est impossible pour un employé de se trouver sans bureau, l'inverse
n'est pas vrai; un bureau pourrait dès lors rester inoccupé. Dans ce cas, on conçoit
qu'il est préférable de mettre la clé étrangère du bureau dans la table Emp 1oye plutôt
que l'inverse.
Relation n-n
La chose se corse un peu avec l'introduction de la table Campus et de son lien avec la
table Facu 1té (voir figure suivante). En effet, une faculté peut se trouver sur plu-
sieurs campus et un campus héberger plusieurs facultés. Si nous nous limitons à ces
deux tables, comment résoudre l'emplacement de la clé étrangère? Elle devrait théo-
riquement figurer dans les deux tables.
Plaçons-nous du côté Faculté. La présence de plusieurs facultés sur le même
campus« 1 » se fait par les enregistrements suivants: 1-1, 2-1, 3-1, 4-2, 5-2 (voir
tableau 5-1). Malheureusement, cette manière de faire ne permet pas de dire que la
faculté « 1 » se trouve aussi sur le campus « 2 » . L e même problème se poserait du
côté de la table Campus.
ld_primaire_faculté Id_étrangère_campus
1 1
2
3 1
4 2
5 2
2 2
3 1 2
4 2 2
Employe
PK id matricule
nom Faculte
prenom
fonction
- PK iQ fj!~l!lt~
adresse_courriel
nom
no_telephone
nbreEmployes
- FKl id_service
nbreServices
Service
PK id s~rvice -
Faculte_Campus
nom
adresse - PK ig fi!~'-! 11~ ~i! mRl!~
telephone
nbreEmployes FKl id_faculte Campus
FKl id_faculte_campus FK2 id_ campus L__
nbreEmployes
PK id cam12us
nom
adresse
Vl
La problématique de la mise en correspondance relationnel/objet
Q)
,_
0 Peut-être vous trouvez-vous un peu dérouté par ces deux méthodes représentant la
>-
w même information : le relationnel d'un côté et !'orienté objet de l'autre. En fait, c'est
N
..-1
leur histoire respective qui justifie ces deux méthodes et leurs différences, et plus d'un
0
N
informaticien y a perdu son latin (euh,« son assembleur»).
@ Le relationnel se préoccupe du stockage efficace des données. Il se doit de fonc-
~
.c tionner quel que soit le mode final de stockage de données, que ces données soient
Cl'I
·c
>-
0..
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
Avec Django
Django vous épargne de saisir parfaitement cette mise en correspondance et vous fait
grâce de ces différences en ne travaillant que dans un esprit orienté objet (bien que
les données se trouvent finalement stockées dans un mode relationnel). En Django,
le modèle de données est réalisé sous la forme d'un diagramme de classes (voir
chapitre 3) en utilisant tous les modes possibles de mise en relation entre objets
(association et héritage). Travailler sous Django vous permet de le faire dans un
«esprit objet», jusqu'à ne rien connaître du fonctionnement des bases de données
relationnelles. Cette indifférence vis-à-vis du relationnel et du langage SQ!_, est une
des qualités parmi les plus appréciées de Django.
Néanmoins, cela ne dispense pas d'une compréhension, fût-elle sommaire, du fonc-
tionnement des bases de données relationnelles (nous décrirons un peu de SQ!_, au
prochain chapitre), qui restent à la base de tout site dynamique.
Vl
Q) Retour au modèle de données de Trombinoscoop :
0L..
>-
son diagramme de classes
U.J
N Après cette parenthèse rappelant les principes de base du modèle relationnel, repre-
T"'f
0
N
nons sans plus attendre notre cahier des charges du début du chapitre et réfléchissons
@ aux données qu'il sera nécessaire de stocker dans une base pour réaliser Trombinos-
...... coop. Cette étude se fera dans une perspective pleinement objet et fera appel au dia-
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
gramme de classes, même si les données sont finalement stockées et gérées dans une
base de données relationnelle.
Employé ~tudiant
+Bureau +Année
Vl
Q)
,_
0
... qui travaillent ou étudient à l'université
>-
w
N L e lecteur attentif aura remarqué qu'il manque dans ce modèle certains attributs
.--1
0 pourtant présents dans nos maquettes graphiques. Par exemple, la faculté des utilisa-
N
@ teurs ne se retrouve nulle part. De même, aucun attribut ne permet de stocker le
~
.c
Cl'I
·c
>-
0..
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
Personne
+Nom
+Prénom
+Date de naissance
+Matricule
+Courriel
Faculté
+Téléphone fixe
+Téléphone mobile Nom
1
+Mot de passe Couleur
Fonction
+Intitulé
Employé Étudiant Cursus
+Année o.. • 1 +Intitulé
Campus
Nom
Adresse postale
Figure 5-10 « Personne», « Employé» et« Ëtudiant »agrémentés de leurs objets annexes
Nous avons ajouté le concept de Faculté à Personne ; en effet, qu'on soit étudiant ou
employé, on appartient à une faculté. Les employés ont une Fonction (secrétaire,
Vl
Q) professeur, technicien, etc.) et sont affectés à un Campus (sur lequel se trouve leur
,_
0 bureau). Les étudiants suivent un Cu rs us (par exemple « Master en Sciences
>-
w physiques »).
N
.--1
0
Entre ces concepts, nous avons représenté des liens, dotés de cardinalités. Ces der-
N nières sont faciles à comprendre. Prenons le lien qui relie Personne à Facul té. Le 1
@
~
signifie qu'à chaque personne correspond une seule faculté. Le 0 .. * signifie qu'à
.c chaque faculté peut correspondre entre zéro et une infinité de personnes.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Vl
Q)
0L..
>-
UJ
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Mise en application : un site web inspiré de Facebook
CHAPITRE 5
O.. *
Personne Message
+Nom O.. * +Contenu
O..* +Prénom Date de publication
+Date de naissance
+Matricule
+Courriel
Faculté
+Téléphone fixe
+Téléphone mobile Nom
+Mot de passe Couleur
Fonction
+Intitulé
Employé ~tudiant Cursus
+Année o.. * 1 +Intitulé
campus
Nom
Adresse postale
Vl
Q)
,_
0
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
6
Premier contact avec
les bases relationnelles et SQL
à partir d'un exemple en CGI
Le site web doit pouvoir interroger et modifier la base relationnelle où sont stockées toutes les données
du modèle. Il lui faut pour cela un langage particulier: le SQL. L es notions de SQL dont nous
aurons besoin par la suite, mais qui sont le plus souvent cachées par le Jramework Django, seront
exposées dans un contexte web réalisé en CGI Cette technologie n'est plus de mise aujourd'hui pour le
développement web côté serveur, mais à titre pédagogique, ce chapitre nous permettra de l'évoquer
comme un parfait exemple d'un mélange de genres à éviter.
Vl
Q)
Dans le chapitre précédent, nous avons élaboré notre modèle de données et décidé de
stocker les informations de notre projet dans une base de données relationnelle. Il
nous faut maintenant étudier comment faire communiquer notre site avec ces bases.
C'est le rôle du langage SQ!., (Structured Query Language).
Il y a quelques années, la mise en place de l'interactivité et de la dynamique côté ser-
veur recourait à la technologie CGI ( Common Gateway Interface) . Cette technologie
s'accommode de petits scripts côté serveur, écrits en langage interprété (comme Perl
ou Python) ou en langage compilé (très souvent C++), qui créent sur le fil des pages
HTML pour les renvoyer et les afficher côté client.
Rien ne vous interdit de continuer à la pratiquer, mais vous risquez de sérieux maux
de tête ! Nous vous le déconseillons très vivement, sinon en désespoir de cause ou
pour de très petits projets bien ciblés.
Malgré tout, nous vous la présentons très succinctement dans deux optiques :
• d'une part pour mettre rapidement en pratique les notions de SQ!.., qui vous
seront nécessaires pour comprendre les chapitres suivants, bien que souvent
cachées par les objets de Django ;
• d'autre part pour vous montrer, à titre pédagogique, ce qu'il ne faut pas faire: un
code fourre-tout dans lequel se mélangent indigestement langage de programma-
tion, HTML et SQ!.,.
Pour conduire notre propos, nous allons «construire» un simple carnet d'adresses
web. Trois fonctionnalités seront développées : « afficher tous les employés de
l'université», «les afficher par service» et« ajouter de nouveaux employés ».
En guise d'exemple, nous pourrions développer en CGI notre projet Trombinoscoop. Ce serait de fait une
tâche titanesque et un si gros projet n'est pas utile pour vous donner un aperçu de la technologie CGI.
C'est pourquoi nous allons nous atteler à un projet beaucoup plus modeste : un simple carnet d'adresses
électronique.
Aussi modeste soit ce carnet d'adresses, nous n'allons pas nous épargner la phase
d'analyse, afin de déterminer exactement ce que l'on veut développer et d'esquisser le
Vl
Q) résultat final attendu.
0L..
>-
UJ
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Premier contact avec les bases relationnelles et SQL à partir d'un exemple en CGI
CHAPITRE 6
Figure 6-1
Cas d'utilisation Carnet d'adresses
du carnet d'adresses
Figure 6-2
Maquette des écrans -
du carnet d'adresses ©@ •n•I 1 Pt
'~ '
Bienvenue sur le site de l'ULB
Que-·--....,..,.,.,. ?
• l.lil a:!Rllll:a• ~llS
. --- · "'-'-##-Â.#~
. 1;..1- '··- .....
~- ·--
I
/
y Pl
-
©êJ "'"''- 1
©@ '""'' 1 Pl
Employé du service •• ~riptions »
LP1.,,.. Alcxr.
Bienvenue sur l'eCarnet de l'ULB 2.....,,...S.C,.,,...
Employh
1 , •.,.... ........ 021223'156
l_____..- L----'
2, ~llus ... 027223'157
Employés ""'"Ht'li«
IINcnp•-1• 1( Wtcr J
-
~
,_
Ajou!UWl"°"""I~
lt»M
Mat1'culc : t•
1
1
1
-
T41.ltxc
1 AJOU'"
(0272ZJ455
\IAs<"!'-
1
ffi
... ©@
r
., ,..1_
Ajout de l'employé « Xovier Devos »
1 Pl
-
Ce modèle est dit « conceptuel », car il ne représente pas exactement les tables que
nous allons implémenter dans la base de données. Plusieurs modifications d'ordre
technique doivent être apportées au modèle.
• La plus importante est l'ajout de clés dans les deux tables. Nous avons vu que
toute table devait posséder un attribut identifiant chacun de ses enregistrements
de manière unique.
Pour la table Emp 1oyé, le matricule constituera parfaitement la clé primaire. En
revanche, aucun attribut de la table Servi ce ne peut jouer ce rôle. Nom, par exem-
ple, n'est pas un bon candidat de clé, car on peut très bien imaginer plusieurs
services qui portent le même nom au sein de l'Université (par exemple
«Secrétariat»). On va donc ajouter un attribut nommé I d.
Cet Id de service sera également la clé étrangère de la table Emp 1 oyé, sous le nom
ID- Servi ce. Uajout de ces deux attributs d'identification dans les tables Emp 1oyés
et Servi ce n'est rien d'autre que l'expression concrète de la relation 1- n qui unit
les deux tables.
• Les majuscules, espaces et accents doivent être supprimés, car les bases de don-
nées n'en sont pas friandes.
Notre modèle va donc devenir le suivant:
,_
0
>-
w
N
.--1
Création de la base de données avec SQLite
0
N
Pour notre base de données, nous allons utiliser le logiciel libre SQJ_,ite. Il s'agit d'un
@
~ système de gestion de bases de données (SG BD ) très léger et très facile d'emploi, qui
.c
Cl'I
·c
n'utilise qu'un unique fichier pour encoder les bases de données. Ces dernières sont
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Créer notre base de données à l'aide de SQJ_,ite D atabase Browser, sur la base du
modèle que nous nous sommes défini, est assez élémentaire. Vous devriez rapide-
ment obtenir le résultat de la figure suivante.
Figure 6- 5
Création de la base de données •• . .
fie Edit View Help
SQlite
D ~ riil ~ ml' d At mt of ~ ~?
Oatabase Strucbse f&OWse Data 1 Execute SQl 1
- Name I Ob~ct 1Type 1Schema
EJ--employe table CREATE TABLE e...
1 [···mabiwle field INTEGER PRIMARY KEY
1 t·"nom field TEXT
; r ··prenom field TEXT
Î ~···date de naissance field TEXT
f ~.. ·courrie - fidd TEXT
! tel
~... fixe field TEXT
1 t··tel=mobie field TEXT
1 '-··id service field NlMR.IC
Ëh er.,,; table CREATE TABlf s ...
t···id field INTEGER PRIMARY KEY
r ·nom field TEXT
L•••emplacement field TEXT
Notez que chaque attribut doit être typé et que trois types de données ont été
utilisés: TEXT, NUMERIC et INTEGER PRIMARY KEY . Nos champs sont pour la plupart
Vl
textuels. Un nom, c'est du texte. Un téléphone en est aussi, car il peut contenir des
Q)
caractères non numériques (par exemple le numéro +32 (0)789 56 78 90). Seuls nos
,_
0
>- identifiants et notre matricule sont numériques ou entiers. Oyant à INTEGER PRIMARY
w
N
KEY, c'est tout simplement la clé primaire.
.--1
0
N
Une fois la base de données créée, n'hésitez pas à vous familiariser avec ce logiciel
@ élémentaire et à y encoder quelques données d'exemple.
~
.c
OI
·c
>-
0..
0
u
Premier contact avec les bases relationnelles et SQL à partir d'un exemple en CGI
CHAPITRE 6
DÉFINITION SQL
Le sigle de ce langage signifie Structured Query Language, ou « Langage de requêtes structurées».
C'est devenu le standard incontournable du <c monde relationnel » et toute application informatique
devant s'interfacer avec une base de données relationnelle, ne peut le faire qu'en «s'exprimant» dans
ce langage.
SQL est un standard bien installé aujourd'hui, que l'on retrouve à l'œuvre chez tous les acteurs impor-
tants du monde des bases de données relationnelles, tels MySQL, PostgreSQL, Oracle, Microsoft Access,
Sybase ou lnformix. Il est devenu partie intégrante du matériel de base que tout informaticien se doit
d'inclure dans ses bagages pour monter à l'assaut de son premier sommet web.
UPDATE Nom_de_1a_tab1e
SET Colonne = Valeur
[WHERE qualification]
Si la requête porte sur plusieurs tables mises en relation (par exemple obtenir tous les
employés travaillant dans le deuxième service), il faudrait écrire :
0L.. Ce que l'on trouve dans le WH ERE est une condition de jointure. C'est grâce à elle que
>- l'on va préciser comment chaque enregistrement d'une table peut être lié à un ou plu-
U.J
N sieurs enregistrement(s) d'une autre table. C'est ici que se met en place le lien reliant
..-!
0 les deux tables et qui apparaît dans le graphique de la base de données : en égalisant
N
@ ces deux clés, on peut passer d'une table à l'autre.
..... Voici maintenant une requête qui se limite à corriger le nom d'un des employés :
..c
en
ï::::
>-
a.
0
u
Premier contact avec les bases relationnelles et SQL à partir d'un exemple en CGI
CHAPITRE 6
Ce script démarre l'exécution d'un serveur web à même votre ordinateur sur le port
local 8080. Pour accéder à notre site web, nous devrons donc introduire l'adresse
http://localhost:8080 dans notre navigateur.
DÉFINITION Port
Un port est un canal de communication que votre ordinateur met à disposition pour communiquer avec
d'autres.
Vl
Nous venons de créer un serveur CGI basique. Il permet de servir deux types de pages :
Q)
0L.. • des pages statiques : toutes les pages placées dans le répertoire qui contient notre
>- script seront servies de manière statique. C'est là qu'on va placer nos pages écrites
UJ
N en pur HTML et qui ne comportent aucun code Python.
.--!
0
N
• des pages dynamiques: toutes les pages placées dans le sous-dossier cgi - bi n
@ seront d'abord envoyées à l'interpréteur Python.
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Requf tt HTTP
Système ~e fichiers
.
.
Ordinateur du visiteur
Se rend sur http;//locolhost:8080/welcome.html
•
ri
welcome.html
lteoutt~ H Til'
--+ lq;1l 4 SQL •
~
cgl-bln/ecartt_home.py database.sqlite3
~
~
Figure 6-7 Comportement du serveur web lorsqu'on visite la page« cgi-bin/eCarnet_home.py »
Vl
Q)
D ans le premier cas, on visite une page statique. Le serveur web va donc simplement
,_
0
>- la chercher dans le système de fichiers et renvoie son contenu.
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Premier contact avec les bases relationnelles et SQL à partir d'un exemple en CGI
CHAPITRE 6
•
1
+- -+ <! Q 127.0.0.1:8080/welcome.hunl
#!/usr/bin/env python Ct
# - '~ - coding: utf-8 - '~ - e
import sqlite3 E)
Figure 6-9
Page principale de notre
carnet d'adresses ~ ~ C 0 localhost:SOBO/cgH:wl/ecarnet_home.py- - -
Nom : L
Matricule : ._________,
SQ!_,ite, laquelle crée un objet que nous stockons dans la variable db_connecti on .
C'est sur cet objet que nous enverrons nos requêtes SQL.
Ensuite, nous allons récupérer les listes des employés via SQ!_,. On procède d'abord à
l'obtention d'un objet cursor 0 qui envoie la requête SQ!_, SELECT à la base de don-
nées et en récupère les résultats : noms, prénoms et numéros de téléphone f).
Les résultats renvoyés par la base de données sont extraits via la méthode fetcha 11
du curseur. Ils sont placés dans une variable liste que nous nommons rows C!). Nous
pouvons maintenant parcourir cette liste à l'aide d'une boucle Ci) pour passer en revue
tous ses éléments. À mesure que l'on parcourt l'ensemble des résultats, on crée les
éléments HTM L <l; > de notre liste 4l!). Une fois la liste construite, nous pouvons
passer au formulaire de recherche des employés d'un service. La première ligne écrit
le titre en H TML 4D. Ensuite, nous créons un formulaire H TML qui va contenir
deux champs :
• une liste de choix reprenant tous les services disponibles @ ;
• un bouton de soumission œ.
À la soumission du formulaire, nous aimerions être redirigés vers le script
eCarnet_servi ce . py. C'est ce que mentionne l'attribut action de l'élément fo rm œ.
Pour établir notre liste de choix avec tous les services, nous devons également faire
une requête sur la base de données œ
et boucler sur les résultats afin de créerœ
toutes les « options » possibles.
Nous créons de manière similaire le formulaire d'ajout d'un employé, dont nous vous
laissons le plaisir d'analyser le code.
Il est important de toujours « clôturer » toute interaction avec la base de données, de
manière à libérer celle-ci pour de nouveaux usages. Cette obligation est satisfaite par
l'entremise de l'instruction db . close() fi .
Vl Une fois le script terminé, le HTML résultant est envoyé en réponse à la requête
Q)
import sqlite3
import cgi
form = cgi.FieldStorage()
service_id = str(form["service"].value) O
db_connection = sqlite3.connect('database.sqlite3')
db_connection.row_factory = sqlite3 . Row
cursor = db_connection.cursor()
cursor.execute("SELECT nom FROM servi ce WHERE id=" + service_i d)
row = cursor.fetchone()
service_nom = str(row['nom']) f)
cursor . execute("SELECT prenom, nom, tel _fixe FROM employe WHERE id_service="
.,. + service_i d) C»
rows = cursor . fetchall()
db_connection . close()
Vl
Q)
0L..
La subtilité dans ce script, par rapport au précédent, est le passage d'un paramètre 0 -
>-
UJ En effet, ce code permet de lister les employés d'un service en particulier. Mais
N
.-f
0
lequel ? Cette information doit bien lui être transmise ...
N
@
Au niveau H TML, le paramètre a été défini dans le formulaire de notre écran décrit
...... précédemment, dont revoici le code tel que créé par Python :
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Un attribut H TML est important ici : l'attribut name du se l ect, dont la valeur est
servi ce. Le service sélectionné par l'utilisateur sera bien transmis via un paramètre
nommé servi ce. La valeur qui sera donnée à ce paramètre sera son id, puisque c'est
ce que nous avons mis dans les attributs va1 ue de chacune des « options». Ainsi
donc, si l'on choisit le service «Inscriptions» et si l'on clique sur le bouton, l'URL
appelée sera la suivante : http://localhost:8080/cgi-bin/eCarnet_service.py?service=2.
Il reste à récupérer la valeur de ce paramètre dans notre script eCarnet_servi ce. py.
Cela se fait via les lignes suivantes que nous rappelons ici :
import cgi
Nous devons utiliser la bibliothèque cgi . E nsuite, la méthode Fie l dStorage récu-
père, sous forme d'un dictionnaire, l'ensemble des paramètres passés au script Q . On
en extrait alors l'élément nommé servi ce, avant de le convertir en un string car il
servira à construire les requêtes SQ!,, qui sont des requêtes textuelles.
Le reste du code de notre page liste les employés d'un service. On récupère d'abord
e
dans la base de données le nom du service (à ce stade, on ne connaît que son i d) afin
de pouvoir personnaliser le titre de la page E). Ensuite, on récupère tous les employés
Vl
du service en question à l'aide d'une requête SQ!, plus ciblée 0 et on les affiche C).
Q)
Figure 6-10
Page affichant les employés eCarnl!!t • Employt!s dun ~rv
import sqlite3
import cgi
db_connection = sqlite3.connect('database.sqlite3')
db_connection.row_factory = sqlite3.Row
cursor = db_connection.cursor()
O cursor . execute("INSERT INTO employe(matricule, prenom, nom, tel_fixe,
• id_service) VALUES(?, ?, ?, ?, ?)",
(matricule, prenom, nom, tel _fixe, id_service))
db_connection.commit() f)
db_connection.close()
print <hl>Aj out de l'employé« ' + prenom + ' ' +nom+ ' »</hl> '
print <P> ' + prenom + ' ' + nom+ ' a bien été ajouté dans la base
de données . </p>'
print ' <P><a href="eCarnet_home.py">Retour au eCarnet.</a></p>'
print ' </body>'
print '</html>'
L'insertion d'un nouvel enregistrement dans la table des employés se fait par l'exécu-
tion sur l'objet cursor d'une requête INSERT dont les valeurs nécessaires (VALUES)
sont obtenues via le formulaire form Q . Notez les points d'interrogation de la
requête qui sont remplacés automatiquement par les valeurs spécifiées dans le
deuxième paramètre de la fonction execute. C'est un raccourci d'écriture non négli-
geable car cela évite de devoir construire le string de la requête par concaténation.
L'exécution seule de la requête ne suffit pas. Il faut également penser à faire un
commit f) sur le curseur afin que les données soient effectivement enregistrées dans
la base de données. U ne fois le nouvel employé ajouté, on affiche un message pour
expliquer que « tout va bien » et on propose un lien permettant de revenir à la page
principale de notre eCarnet. Visuellement, le code donne ceci :
Figure 6-11
Ajout d'un employé dans .Carnet · AJOlll d ùn employé
,_
0 Retour au eCamet.
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Premier contact avec les bases relationnelles et SQL à partir d'un exemple en CGI
CHAPITRE 6
Vl
Q)
Ai-je bien compris?
0L..
>- • À quoi sert le langage SQJ_, ?
U.J
N
• Comment, en CGI, un serveur peut-il servir à la fois du contenu statique et
T"'f
0 dynamique?
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
Mise en application
avec Django
Dans cette deuxième partie, nous allons construire notre site Trombinoscoop en
nous appuyant sur le framework Django. Nous détaillerons chacune des étapes
d'élaboration d'un site web :
• «vues» Django (correspondant à l'aspect Contrôle du MVC) ;
• « templates » Django (correspondant à l'aspect Vue du MVC) ;
• formulaires ;
• «modèles» Django (correspondant à l'aspect Modèle du MVC);
• gestion des sessions ;
• suppléments en Ajax.
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
7
Les vues Django :
orchestration et architecture
Ce chapitre va nous lancer dans l'utilisation du framework Django et nous permettre d'en découvrir
les premiers aspects: URL et « Views ». MVC, la recette de conception fondamentale de tout
développement web mise en place par Django, commencera à être mieux comprise. Un premier projet
Django sera réalisé se bornant à renvoyer une page HTML très élémentaire, un peu comme on le
ferait pour une application statique toute basique.
SOMMAIRE
~ Le modèle MVC selon Django
Vl
Q)
~ Utilité des vues
0L..
>- ~ Définition des URL
UJ
N ~ Définition des méthodes « vues »
..-!
0
N ~ Création d'un projet Django dans Eclipse
@ ~ Réalisation de notre première page web
......
..c ~ Démarrage et test d'un projet dans Eclipse
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Django, le framework que nous allons utiliser pour développer notre site web Trom-
binoscoop, obéit à la philosophie de développement MVC. Comme nous l'avons vu
dans les chapitres précédents, cette architecture se propose de découper le développe-
ment et le code en trois grandes parties :
Django et le MVC
Bien antérieur à Django, le modèle MVC ne lui est pas spécifique. Il est également proposé par de nom-
breux autres frameworks tels que Symfony pour PHP.
I.:objectif de ce chapitre est d'étudier les vues Django. On peut se passer des deux
autres composantes (le modèle et les templates) pour réaliser un site web fonctionnel,
mais on ne peut en aucun cas se passer des vues.
Vl
Q) Ce chapitre sera également l'occasion de commencer le développement de notre site
0L.. « Trombinoscoop ». Le développement sera très progressif afin de vous permettre
>-
UJ d'appréhender pas à pas chacune des composantes de Django. Le premier pas sera
N
.-f une page d'accueil affichant un message de bienvenue. Attendez un peu pour des
0
N pages web plus riches en fonctionnalités et en contenu !
@
......
..c
en
ï::::
>-
a.
0
u
Les vues Django : orchestration et architecture
CHAPITRE 7
Ordinateur du visiteur
Se rend sur http:// www.monslte.com/welcome
Imaginons qu'un internaute désire se rendre sur notre site web, et plus précisément sur la
page d'accueil de ce site dont le nom est we1 corne . Il entre l'URL http://www.monsite.com/
welcome. Nous verrons par la suite par quoi il faut remplacer www.monsite.com dans cette
URL, car il est évident que vous ne possédez pas ce nom de domaine. Le navigateur
contacte notre serveur web et lui envoie une requête HTTP, dans laquelle on retrouve :
• le nom de la page, dans notre cas we 1 corne ;
• les éventuels paramètres passés à la page (aucun dans notre cas, car nous allons
pour l'instant laisser cet aspect de côté) ;
• diverses informations au sujet de l'internaute : la version de son navigateur, sa lan-
gue, etc.
À la réception de la requête, le serveur web la transmet telle quelle à Django, charge
à ce dernier de la décoder et d'agir en conséquence.
Vl
Q) Le premier rôle des vues Django est alors de lister toutes les pages possibles ou, en
,_
0
d'autres mots, toutes les URL possibles. Dans notre exemple, il va falloir préciser que
>-
w l'URL welcome existe et qu'il y aura du traitement à faire dessus. Pour chacune des
N
..-1 URL possibles, on précise quelle fonction Python doit être appelée pour traiter la
0
N requête et, au final, écrire le HTML à renvoyer au navigateur. Les traitements réa-
@ lisés par ces fonctions constituent le deuxième rôle des vues Django.
~
.c
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Le fichier urls. py
La définition des URL possibles se fait dans un fichier nommé url s . py. Il contient
essentiellement une liste de correspondance entre des U RL et des fonctions Python :
urlpatterns = patterns('' ,
( ' Awel come$', myproject.vi ews.welcome),
('Alogin$', myproject .views . login),
('Alogout$', myproject . views . logout),
('A$', myproject .views .welcome)
)
url patterns est une liste Python qui contient toutes les correspondances URL/fonc-
tion à appeler. Il est important que cette liste porte ce nom-là : Django attend cette
dénomination précise. Par ailleurs, cette liste doit respecter un certain format, d'où
l'usage de la fonction patterns, qui construit une liste de correspondances dans le
format attendu par Dj ango.
Le premier paramètre de la fonction patterns est un prejix. Laissons-le de côté car
nous n'allons pas l'utiliser et, comme vous pouvez le constater, nous le laissons vide.
Ensuite, on ajoute à la fonction autant de paramètres qu'il y a d'URL dans notre site
(pour notre exemple, nous avons défini quatre URL, donc la fonction prend quatre
paramètres en plus du prefix), comme ceci :
Tous ces paramètres supplémentaires sont des tuples qui mettent en correspondance
chaque URL et la fonction Python à appeler. Ils sont construits sous la forme suivante :
Vl
Q)
Qye contiennent exactement ces tuples ?
0L.. • « URL » est une expression régulière. Dans nos exemples, nous utiliserons exclusive-
>-
U.J ment des expressions régulières triviales qui font correspondre une fonction Python
N
T"'f à une et une seule chaîne de caractères. Retenez simplement que, dans ce cas,
0
N l'expression régulière se résume au nom de la page entouré par les caractères Aet $.
@ • « Fonction à appeler» est simplement la fonction Python à appeler en réponse à
.....
..c l'appel de cette U RL.
en
ï::::
>-
a.
0
u
Les vues Django : orchestration et architecture
CHAPITRE 7
Il s'agit d'un motif qui permet de décrire une ou plusieurs chaîne(s) de caractères possible(s). À l'aide des
expressions régulières, on peut, par exemple, exprimer la correspondance suivante « pour toutes les URL
qui commencent par article - on appelle la fonction Python affi cherUnArti cl e ».
Le fichier views. py
Le rôle du fichier vi ews. py est de définir toutes les fonctions Python déclarées dans
les tuples. Ces fonctions sont appelées des «vues ».
Chacune de ces vues reçoit toujours en entrée un objet représentant la requête
HTTP et dont les informations transmises pourront être exploitées. Pour fournir une
réponse HTTP à la requête qu'elle a reçue, chaque vue doit construire une page
HTM L à renvoyer vers l'utilisateur. D 'un appel à l'autre de cette même fonction, le
HTM L renvoyé pourra être différent. Là réside toute la saveur et la subtilité de la
mise en place de sites web dynamiques : leur contenu évolue au fù du temps.
Sans plus attendre, passons à un exemple de fichier vi ews . py .
Vl
Q) from django.http import HttpResponse f)
0L..
>- def welcome (request) : 0
U.J
return HttpResponse('<html><body><p>Bienvenue !</P></body></html>')
N
..-!
0
N Dans ce fichier, nous avons défini une fonction nommée we l corne 0 , laquelle sera
@ appelée lorsqu'on entrera l'URL http://www.monsite.com/welcome (comme défini dans
......
..c
en
url s . py) .
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
r
Serveur web - www.monsite.com
Django
~ wokom•O
rf'UJtn
Hl~
.........,.,.
<p>Nws
Ujuiht1fll2
</p>1
Ordinateur du visiteur
Se rend sur http://www.monsire.com/welcome
<-p>NOUi
"""""""'
22julllfl 2012.
~-</p-_>î:H
""T"°'
M '""'
l fï,,_..
ma'":-.
1
~~~~~~~~
On constate qu'à la réception de la requête, Django va avant tout trouver une correspon-
dance entre la page demandée et une vue Python. La vue trouvée, Django va l'appeler,
charge à celle-ci de produire en retour le HTML qui sera renvoyé tel quel en réponse.
Jusqu'à présent, l'exemple reste théorique et nous ne l'avons pas encore codé réelle-
Vl
Q)
ment dans notre éditeur Eclipse. D e même, le résultat n'est pas encore apparu dans
,_
0 un navigateur. Remédions-y en découvrant comment, très pratiquement, réaliser
>-
w cette petite application dans E clipse.
N
.--1
0
N Installation d'Eclipse
@
~ Nous expliquons comment installer notre environnement de développement dans l'annexe A.
.c
Cl'I
·c
>-
0..
0
u
Les vues Django : orchestration et architecture
CHAPITRE 7
• t • •
•
.. ,.. Select a wizard
Welcome to Eclipse
_J
*
i;l
lava ProjKt from Existing Ant &Jldfile
Plug<n P,oject
.. =- wtt.1·~Hew
'
lil
Ill
li)
~ Getleral
fil (i;i. CVS
121- .Ja••
(à. Plug<n O.-.lopmcnt
8 (3 Pyllev
mM·•·,tJI&wm•
~ Pvllev GoOQle Et>Qine P>oiect
l>lJfl
fi Py()ev l'>O)e<t
Après avoir cliqué sur Next, un assistant de création de projet se lance. À la première
étape, il suffit de donner un nom au projet.
Cliquez alors sur Next. L'écran suivant demande quelle version de Django utiliser
ainsi que quelques paramètres relatifs à la base de données. Les valeurs par défaut
Vl
peuvent être laissées.
Q)
,_
0 Cliquez sur Finish . Le projet est créé et apparaît dans l'écran principal d'Eclipse.
>-
w Remarquez que plusieurs fichiers sont déjà créés, dont u r l s. py. C'est normal, car
N
.--1 nous avons créé un projet de type « Django » et Eclipse sait quels fichiers doivent
0
N obligatoirement figurer dans un tel projet.
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
ml
PyOev Django Projed: Django Settlngs
Ct"4to • new Pydov Djongo Proje<t. Basic Djongo Settings
General
O)ango-sron 1..4orlaœr
Pro}ttt cont~ts:
Datoba<e setlinos
El Use slefault
DatabaseL1>Qr>e 1 SQlte3
r~ 1 _J tt<moe
Database (:!;>me ~ts and Settinos'Pierre\worl<si>acel:rrorttiloscoop\sQI
Pro)ect type
Oioose th~ pro~ type
Databaset10st r-
Database f'W't
0 Py11lon 0 lvlhon 0 Iron Pylhon
ltse<name
Grammar Ver$ion
eassword
2.7
lnterpreœr
Jo•fault H
dlck. here te confiourie àn il'l~ror~ter not lstect.
0 !del projod dtoctory to tho PYTHOllPA11'11
0 Ct~ate 'srê folder and add it to the PYTHOl\P,6.TH1
0 Don'tconfiglse PYTHOl>PATH (ID be done marualy laœr on)
Figure 7-5 Deuxième étape de la création d'un projet Figure 7-6 Troisième étape de la création d'un projet
61 Tront>lnoscoop
a œid·:...;..1••1
lf3' _ nt_.py
li!l setlings.py
Ill li!l ur!s.py
l# li!) 'NSQl PY 0
51@ manage.py
' main
Ill· ~ ~111-;;;, 2. 7(c:'Progam Aleslpy1"on27
Vl
Q) -''-----
f!t Probloms 1:l
,_
0
Qï~
>-
w
Deso'lpbon •
N
.--1
0
N
@
~
!B 1 items selected
.c
Cl'I
·c Figure 7-7 Le projet fraîchement créé
>-
0..
0
u
Les vues Django : orchestration et architecture
CHAPITRE 7
W Team
Validation
00 Web
itl XML
1Reswe Qefaults 11
~· 1
® 1 OK 11 cancel 1
Le fichier urls.py
Nous pouvons maintenant directement éditer le fichier url s . py en double-cliquant
dessus. Remplacez tout le code préexistant par celui-ci:
EXEMPLE 7 .3 Contenu de notre premier fichier urls.py
urlpatterns =patterns('',
('Awelcome$', welcome)
)
À l'aide de ce code, nous avons prévu une seule page (( fonction », nommée we 1 corne .
Un indicateur rouge dans la marge indique qu'Eclipse ne trouve pas la méthode
myproject . views . welcome
Pas de panique ! C'est tout à fait normal: nous ne l'avons pas encore définie et
Eclipse ne peut pas la sortir de nulle part.
Le fichier views.py
Le fichier vi ews . py n'est pas créé par défaut ; il faut le faire manuellement. Pour cela,
cliquez-droit sur le dossier Trombinoscoop qui contient nos autres fichiers et choi-
sissez New > PyDev Module .
Figure 7-10
' If PyOev Package Explor.,. l;;3, = El ~ "~----------
Ajout d'un module El ~ ]< "' from d j an90.conf.urls import: p
S ~ Trombiioscoop
13 @ rip·1mmiiiiiiiiii"iiuirrl~
~
pa~i:~c;er~n~s~·~pa~c~i:~er~n~s~·
n Proj~ct. .. ',. view
œ'J - Go Into
--------i [j File
œ@~ liiiCopy
Vl
Q)
œlê) fj Folder
,_
0
8 ~m ~ Paste
[lî' PyOev Mod"e
>-
w tt )( Oelete QI PyOev Package
Gl ~ p - Move ...
N
.--1 Rename .•. n other... Cb1-IN
0
N .}... Îmnt"W't
@
~
.c
Cl'I
Dans la fenêtre qui apparaît, précisez le nom du fichier (vi ews) sans l'extension py .
·c
>-
0..
0
u
Les vues Django : orchestration et architecture
CHAPITRE 7
Figure 7-11
Deuxième étape de l'ajout d'un
•..-,.
module
CrMte a ~w Python modtJoe ~~
SourCl!Foloo /TrO<Tblnoscoop l a.-~ ...1
Pad<age [ Trombinoscoop l a.-~ ... 1
Name ~ws 1
1~le: Class
Module: Main
Tem~te ~
1Modu~: Unittest
Modu~: Ul'llttest with setup and tearOown
Cliquez sur Finish et le fichier est créé. Vous pouvez maintenant y ajouter le code
suivant:
def welcome(request):
retu rn HttpResponse (' <?xm 1 ver si on="l. O" encodi ng="UTF-8" ?> \
<!DOCTYPE ht ml> \
<html xmlns="ht tp ://www.w3 .org/1999/xhtml"> \
<h ead> \
<t i t l e>Trombinoscoop</ti tl e> \
</head> \
<body> \
<p>Bienvenue sur Trombinoscoop !</P> \
</body> \
</html> ')
Vl
Q) Nous avons cette fois-ci écrit un HTM L plus complet et correct. Pour gagner en lisi-
,_
0
bilité en ne tassant pas tout sur une seule ligne, on utilise des barres obliques
>-
w inverses (\ ) pour signaler que la chaîne de caractères continue à la ligne suivante.
N
..-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Et voilà ! Tout le code de notre première page a été écrit. Il reste un petit détail à
régler avant de tester le résultat.
1 DEFAULT_CONTENT_TYPE = 'application/xhtml+xml'
Figure 7-12
Bouton permettant le démarrage du serveur web
Ne cliquez pas encore dessus, car il faut d'abord se positionner au niveau du projet en
le sélectionnant dans l'explorateur de fichiers.
Ensuite, on peut cliquer sur l'icône «play» verte, ou plutôt sur sa petite flèche
annexe qui affiche un menu déroulant. Choisissez Run As > 1 PyDev: Django .
t
Démarrage du projet C!!J 1 Trombinoscoop Trombinoscoop
Rm As • dj 1 PyDev · O]ango os
Rm Conflgurabons ..• fi 2 Python unit-test
À ce stade, Eclipse lance une série de validations du code et démarre le serveur web.
Vl
Q) Si tout s'est bien passé, dans la console on doit lire le texte suivant:
,_
0
>-
w
N
.-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Validating models . . .
0 errors found
Django version 1 . 4, using settings 'Trombinoscoop.settings'
Development server is running at http://127 . 0. 0. 1:8000/
Quit the server with CTRL- BREAK.
Un message nous indique également par quelle adresse est accessible le serveur web :
http: //127. 0 . 0 . 1: 8000/. Il s'agit en réalité de l'adresse IP locale de votre machine.
Vous comprenez donc maintenant pourquoi et comment remplacer le http://www.mon-
site.com/ que nous avons utilisé de manière fictive tout au long de ce chapitre.
Notez également que l'adresse proposée dans la console contient un numéro de port
(8000). D'habitude, lorsqu'on consulte un site web, on ne spécifie pas ce numéro de
port. Par défaut en effet, les navigateurs utilisent le port 80 et les serveurs web sont
configurés pour tourner sur ce dernier. Cependant, comme ici le serveur web exploite
un autre port, il faut le spécifier.
D onc, pour tester notre premier site web, il suffit de lancer un navigateur et de se
rendre à l'adresse suivante : http : / /12 7 . 0. 0 .1 : 8000/we 1corne . Le rendu sera le
suivant:
Figure 7- 15
Résultat de notre première Trombiooscoop
Vl
Q)
,_
0
>-
w
N
..-1
0
N
@
~
.c
OI
·c
>-
0..
0
u
Les vues Django : orchestration et architecture
CHAPITRE 7
Vl
Q)
0L..
>-
U.J
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
8
Les templates Django : séparation
et réutilisation des rendus HTML
Tout en continuant le développement de notre projet « Trombinoscoop », ce chapitre aide à
comprendre comment la mise en place des « templates » Django tient les instructions HTML (dédiées
à la présentation du site web) séparées des instructions Python (plus centrées sur son
fonctionnement). Le rôle et l'utilisation des templates constituent l'essentiel de ce qui va suivre.
Vl
Q)
0L..
>-
UJ
N SOMMAIRE
..-!
0
N ~ Introduction aux templates de Django qui séparent au mieux le HTML du code Python
@ ~ Description de tout ce que l'on peut faire et produire à partir de ces templates
......
..c ~ La suite de notre projet Trombinoscoop
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Au chapitre précédent, nous avons étudié une des premières composantes du modèle
M T V (Mode/ Templates Views) de Django, à savoir les vues. Cela nous a permis de
réaliser une première page, certes plutôt basique, de notre site web. Cependant, notre
code est entaché de l'affreux mélange de HTML et de Python. Heureusement, les
templates Django sont là pour nous aider à tenir séparés les deux types de codes. Ils
conduisent à réutiliser facilement les lignes de HTM L et à éviter des duplications
intempestives de code.
L'objectif de ce chapitre est d'étudier les templates Django et de les appliquer à la
page de login de notre site web Trombinoscoop.
L'utilisation d'un template s'avère très simple. L'idée est de nettoyer les views de ce
HTML inopportun. Nous n'utiliserons pas le code suivant présenté au chapitre
précédent:
def welcome(request) :
return HttpResponse('<html><body><P>Bienvenue' + logged_user_name
.,. + '</P></body></html>')
À la place, nous allons plutôt tirer profit de la fonction render _to_ response 0,à
laquelle on passe en paramètre un nom de template, suivi de la valeur de tous les
paramètres qui jalonnent le template. Le code HTM L a disparu comme par magie
de l'utilisation des views.
def welcome(request) :
return render_to_response O C'my_template.html',
.,. {'logged_user_name': 'Pierre'})
Vl
EN PRATIQUE Configuration: encore une histoire d'encodage !
Q)
0L.. Deux éditeurs viennent d'être ajoutés: un pour le HTML, un pour les CSS. Il va falloir les configurer pour
>- qu'ils produisent du code en UTF-8.
U.J
N
Cela se fait dans le menu Windows > Preferences. Dans la boîte de dialogue qui apparaît, rendez-vous
T"'f
0
dans la catégorie General > Workspace et changez le paramètre Text file encoding en UTF-8.
N
@
......
..c.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Figure 8-1
Création du dossier qui
contiendra nos templates
If Fok!er
@ PyOev Module
E9 PyOev Padcage
RenëllTie ••.
------ ~ Example •.•
-------
è:::.a lmpo<t ... ~ Othet ... Ctrl#I
~ Export•••
import os
PROJECT_ROOT = os . path.abspath(os.path.dirname(~file~)) 0
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, 'templates'),
) f)
Les deux premières lignes 0 sont à placer au tout début du fichier setti ngs. py. La
définition que nous vous proposons de la variable TEMPLATE_DIRS f) doit remplacer
celle qui existe déjà dans le fichier.
Nous pouvons maintenant créer notre premier template : cliquez-droit sur le dossier que
nous venons de créer et choisissez New> File . Donnez-lui le nom we l come. html . Dans
ce fichier, recopiez tout le code HTML que nous avions placé dans vi ews. py, à savoir:
Vl
Q)
,_
0 EXEMPLE 8.4 Code HTML du template welcome.html
>-
w
N
<?xml version="l.O" encoding="UTF-8" 7>
.--1
0
<!DOCTYPE htmh
N <html xmlns="http ://www.w3.org/1999/xhtml">
@ <head>
~
.c <title>Trombinoscoop</title>
OI
·c
>-
0..
0
u
Les templates Django: séparation et réutilisation des rendus HTML
CHAPITRE 8
</head>
<body>
<p>Bienvenue sur Trombinoscoop l</P>
</body>
</html>
Il ne nous reste plus maintenant qu'à modifier la vue afin que celle-ci fasse appel à
notre template. Pour ce faire, remplacez le code de vi ews . py par le suivant :
EXEMPLE 8.5 Appel du template welcome.html dans la vue
def welcome(request) :
return render_to_response('welcome . html')
Et voilà ! Nous pouvons maintenant redémarrer notre projet pour voir ce que cela
donne, en cliquant sur l'icône 0 .
O errors f ound
Djan90 version 1 . ~, usinQ settin9s 'Trombinoscoop.settin9s'
Development server is running at http : // 127 . 0.0 . 1:8000/
Quit the server with CTRL-BREAK .
Vl
Q)
Testons l'URL dans un navigateur. Nous obtenons exactement le même résultat
,_
0 qu'au chapitre précédent ... si ce n'est que maintenant, notre code HTM L n'est plus
>-
w mélangé à celui de Python ! Cela fait une énorme différence !
N
..-1
0
N
@
~
.c
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Au niveau de notre vue, nous allons transmettre la date et l'heure courante au tem-
plate sous forme de paramètre f).
N'oubliez pas le nouvel import E) pour que Python puisse jouer avec dates et heures.
Voici le résultat dans un navigateur :
Figure 8-4
La date est affichée de manière ~ TrombOnoscoop
Serveur w eb - localhost:BOOO
~ l~~-DJ •~ng~-
·-
w tlcomt h.tml
(awcôor,._I
wekome.httÏli'
Vl
Q)
Figure 8-5 La date est affichée de manière dynamique.
,_
0
>-
w
N
.--1
0
Lorsqu'on visite l'URL http://localhost:8000/welcome, le navigateur envoie une requête
N
HTTP au serveur web l ocal hos t pour lui demander la page we l corne. Immédiate-
@
~
ment après avoir reçu la requête, le serveur web passe la main à Django. Le traite-
.c
OI ment commence dans le fichier url s. py où l'on va tenter de trouver une correspon-
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
dance entre l'URL demandée et une fonction de vi ews. py : dans notre cas,
vi ews . we l come doit être appelée.
La fonction vi ews . we l come appelle alors le template we l come . htm l en lui passant en
paramètre la date du jour. Le moteur Django remplace dans le template la variable date
(ainsi nommée dans le schéma, mais appelée current_ date_ time dans le code) par cette
valeur transmise. Le HTML final est enfin prêt à être renvoyé en réponse au navigateur
client. Superbe division du travail: personne n'empiète sur les plates-bandes des autres.
Les variables
Nous avons déjà vu que les variables étaient entourées de doubles accolades :
Notons que les variables peuvent être des attributs d'objets Python, par exemple :
Vl
Q)
1 <p>Bonjour {{ ma_li ste. 2 }} !</P>
0L..
>-
UJ
N Formatage des variables
.--!
0
N Les variables, avant d'être incluses dans le HTML final, peuvent être formatées à l'aide
@ de filtres. Par exemple, si l'on désire convertir une variable en minuscules, on écrira :
.....
..c
en
ï::::
>-
a.
0
u
Les templates Django: séparation et réutilisation des rendus HTML
CHAPITRE 8
Dernier exemple de filtre, on peut afficher la longueur d'une variable, comme ceci :
{% if personne.sexe == "F" %}
<p>Chère Madame {{ nom }},</P>
Vl
Q)
{% else %}
0L.. <p>Cher Monsieur {{ nom }},</p>
{% endif %}
>-
U.J
N
..-!
0 Remarquez en passant les {% . . . %} pour entourer les instructions alors que nous
N
avions des { { . . . } } pour évaluer des variables.
@
..... On peut également utiliser les opérateurs booléens and, or et not pour construire des
..c
en conditions plus complexes.
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
<Ul>
{% for livre in livres%}
<li>{{ livre.nom }}</li>
{% endfor %}
</ul>
Ce code est assez simple à comprendre : nous itérons sur chaque élément d'une liste
de livres. Et pour chacun, nous imprimons un élément <li> H TML.
Nous insistons sur le caractère élémentaire des instructions des templates: c'est
entièrement voulu par Django et la philosophie MTV. Seuls des traitements simples
doivent être réalisés dans les templates. Les traitements Python compliqués sont à
reporter dans les vues et les modèles. On ne le répètera jamais assez:
template = aspect, control ou views = intelligence.
L es seules différences entre ces deux pages sont mises en exergue. Nous allons créer
un ternplate base. htm 1 contenant le code commun.
Dans ce template de base, nous allons définir des « blocs » qui pourront être redéfinis par
les templates « enfants » qui en dérivent. Utilisons pour cela deux instructions b1 ock :
l'une pour accueillir le titre de la page O et l'autre pour accueillir le contenu f).
EXEMPLE 8.12 Template base.html avec des « blocs ,, à personnaliser par les templates enfants
{% extends "base.html" %}
{% block title %}Copyright{% endblock %}
{% block content %}Ce site est soumis aux l ois du Copyright. {% endblock %}
Figure 8-6 ·-
Wireframe de la page de login
©J (Q1 http~//www. tr-ombrnosc.oop.com
11 Pl
I•
r:::::;t °C
09 1
Courriel ; \piure@vcemple.~ 1
Vl
Q) Mol de pesse : I· · · · · · · · 1
,_
0
>- 1 Se e<>nn«ter 1 Cff.1:,r yn comgte.
w
N
..-1
0
N
@
,. ,.
Vers Io page de
~
.c créo11on de
Cl'I compte
·c
>-
0..
0
u
Les templates Django: séparation et réutilisation des rendus HTML
CHAPITRE 8
Commençons par nous occuper du HTML de cette page. Comme nous l'avons
signalé plus haut, nous allons utiliser les fonctionnalités d'héritage de Django afin de
placer le code HTML commun à toutes les pages dans un template séparé. Allons-y.
Dans le dossier templ ates du projet, créez un nouveau fichier nommé base . html .
Copiez-y le code suivant :
Première instruction, extends signifie à Django que l'on va dériver ce nouveau tem-
plate de base . htm l , plus générique Q. Ensuite, nous donnons le titre « Connexion »
à notre page f) et spécifions un i d pour la balise body (l ogi nPage) Q .
Arrive le contenu réel de notre page de login, avec essentiellement un formulaire et
des champs de connexion. Le formulaire contient trois paragraphes : un pour le
champ Cour ri el , un autre pour le champ Mot de passe et un dernier pour le bouton
de connexion et le lien vers la page de création de compte. Les deux champs textuels
sont précédés par une balise label , qui entoure un texte représentant l'intitulé du
Vl champ C). Par exemple, l'intitulé du champ dont l'i d est emai l est «Courriel: ».
Q)
0L..
Enfin, notez que nous n'avons pas encore précisé l'attribut action 9 du formulaire,
>- ni la destination du lien hypertexte permettant de se créer un compte Q . Nous nous
UJ
N
en occuperons plus tard.
.-f
0 Nos HTML sont maintenant fin prêts. Il reste juste à ajouter une URL dans le
N
@ fichier u r l s . py et une vue. Dans le fichier u rl s . py, nous proposons d 'ajouter en réa-
...... lité deux URL 0 :
..c
en
ï::::
>-
a.
0
u
Les templates Django: séparation et réutilisation des rendus HTML
CHAPITRE 8
urlpatterns = patterns('',
('A$' , login) , O
(' Alogin$', login) , 0
( ' Awelcome$', welcome)
)
Pourquoi deux URL pointant vers la même vue ? La première représente en réalité
l'URL (< vide» (http://localhost:8000/), celle qui est appelée sans aucun nom de page. La
deuxième est celle qui nomme explicitement la page login.
Notez que nous avons également importé la fonction 1ogi n du module vi ews f) et
qu'il nous faut maintenant l'implémenter. Voici donc les lignes que nous ajoutons
dans le fichier vi ews . py.
EXEMPLE 8.18 Trombinoscoop. Lignes à ajouter dans le fichier views.py
def login(request ):
return render_to_response( ' login . html')
1
Tout est maintenant mis en place pour obtenir une première ébauche de notre page
de login. Voyons à quoi elle ressemble dans un navigateur.
Figure 8-7
Première ébauche de la page Trombinoscoop - Connexion
Mot de passe : L
1Se connecter 1 Créer un compte
Vl
Q)
,_
0
>-
w
N
.-1
0
N
@ C'est simple, c'est efficace, mais c'est laid ! Pour améliorer la page et la rendre plus
~
.c fidèle au wireframe, il va falloir composer avec des CSS.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure 8-8
Le logo de Trombinoscoop
trombinoscoop
D oté de ce logo choc, nous pouvons commencer a ecrire nos feuilles de styles.
Créons tout d'abord un fichier style. css qui contiendra toutes nos instructions
CSS. Mais au fait, où créer ce fichier ? L e placer dans l'arborescence du projet ne
suffit pas, car le navigateur web ne saura pas à quelle URL le récupérer.
Les fichiers CSS, tout comme les images ou les fichiers JavaScript, sont des fichiers
statiques. Pour ces fichiers-là, Django propose un mécanisme simple: il suffit de
préciser dans la configuration du framework le dossier où nous placerons tous les
fichiers statiques.
Rendez-vous donc dans le fichier de configuration de Django (setti ngs. py) et com-
plétez les sections suivantes :
CONFIGURATION. Emplacement des fichiers statiques
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path .join(PROJECT_ROOT, 'static'),
)
0
' 1<11: PyDev Package Explorer - l:l
Figure 8-9
Arborescence des fichiers e ~ :::,;, "'
8 Trombinosooop
et dossiers du projet El œTrorrbinosooop
El là :>tatic
El f2::. e:>s
~ style.css
El f.O img
[!') logo.png
f.O JS
El ~ œmplaœs
~ base.hbnl
~ login.hbnl
[;) welcome.hbnl
lfll _ init_ .py
el lè) setti"!IS·PY
lè) tXls.py
œ ŒI 'J!<!Ws.py
œ lèl wsg;.py
Attaquons maintenant le CSS et commençons par styliser notre bannière. Pour l'ins-
tant, celle-ci n'apparaît pas, le contenu de la balise header étant vide. D onnons donc
à cette balise une taille artificielle, colorons son fond en bleu et ajoutons notre logo :
header {
position : absolute;
left: O;
top: O;
height : 80px;
width: 100%;
background: #3b5998 url(' . . /img/logo . png ') 0 no- repeat SOpx 25px;
border- bottom: lpx solid #133783 ;
}
Vous pouvez constater que l'URL de notre image de fond est un chemin relatif par rap-
port à l'emplacement du fichier CSS O (les deux points permettent de « remonter »
d'un répertoire). Il en est toujours ainsi pour les chemins relatifs mis dans des CSS.
Profitons également de ce premier travail dans styl e . css pour supprimer les marges
du body et changer la police de notre document, ainsi que sa couleur :
Vl
Q)
EXEMPLE 8.20 Trombinoscoop. Marge du body et police du document
,_
0
body {
>-
w margin: O;
N
...-1
padding: O;
0
N
font - family : "Lucida Grande", Tahoma, Verdana, Arial, sans -serif;
@
font -size: llpx;
~
co 1or : #000333;
.c }
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Il reste à référencer le fichier CSS dans le HTML de nos pages. D ans le template
base. html , ajoutez la ligne suivante au sein de la balise <head> :
EN PRATIQUE
Bien entendu, on pourrait remplacer href="/st a t i c /css/st yle . css " par un lien vers une
variable: href="{ {STATIC- URL} }".
Figure 8-10
Rendu de notre bannière Trombinoscoop - Connvdon
~ ~ c 0 127.0.0.1:8000
trombinoscoop
1Se connecter 1Crm un COf!1!lli!
body#loginPage section#content { 0
position: absolute; f)
top : lSOpx; E)
left: 50%; e
width : SOOpx; 0
margin: 0 0 0 - 250px; 0
padding : O;
}
form label { 0
display : block;
width : lSOpx;
float : left; e
text- align: right;
padding : 4px lOpx 0 O;
}
form input[type="submit"J { œ
margin: 0 20px 0 160px;
border- style : solid;
border-width : lpx;
border- color : #d9dfea #OelfSb #OelfSb #d9dfea;
background - color : #3b5998;
color : #FFFFFF;
padding : 2px 15px 3px lSpx;
text- align : center ;
}
a { 4D
color : #3b5998;
}
Vl
Q)
On s'occupe tout d'abord de la section d'i d content de la page loginPage O . On la
0L..
>- positionne en absolu f), décalée vers le bas 9 pour laisser la place à la bannière. On
UJ
N
lui donne une largeur de 500 pixels O (la boîte de login ne devant pas être très large).
.-f
0 Petite astuce, on positionne cette boîte avec un l ef t à 50 % 0 et on lui donne une
N
marge négative de 250 pixels Ci). Cela permet de centrer la boîte horizontalement : le
@
...... 50 % positionne le bord gauche de la boîte juste au milieu de la page et la marge
..c
en négative décale la boîte vers la droite de la moitié de sa largeur.
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
On s'occupe ensuite des label 0 du formulaire. On les fait flotter à gauche, à l'aide
de la propriété fl oat Q , qui retire le l abel du flux de positionnement courant et
invite les éléments successifs restant dans le flux (en l'occurrence ici les input) à se
positionner autour de la boîte flottante, et non pas à rester cachés derrière.
Ensuite on modifie légèrement la taille des input de type text Ci). Pour finir, on
habille le bouton de soumission du formulaire œ
et on colore les liens hypertextes m.
Le résultat est visible sur la figure suivante.
Figure 8-11
Rendu de la page de login î romblnoscoop - Connaion
~ -+ c 0 127.0.0.1:8000
trombinoscoop
COllriel :
Mot de passe :
Notre page est certes bien plus jolie, mais pas très fonctionnelle. Si par mégarde on
clique sur le bouton Se connecter (avouez que c'est tentant!), c'est la Bérézina. En
effet, nous avons laissé des points d'interrogation dans l'attribut action. Dès le cha-
pitre suivant, nous allons étudier comment gérer les formulaires.
w
>. • Citez deux avantages des templates.
N • Un template désire réutiliser du HTM L déjà écrit dans un autre. Comment peut-
.--1
o
N
il réutiliser ce code ?
@ • Pouvez-vous décrire le cheminement dans le code Python qui est effectué
:t:Cl'I lorsqu'un internaute visite une page de votre site ?
·c
>-
0..
0
u
9
Les formulaires Django
L'objectifde ce chapitre est d'étudier comment gérer les formulaires HTML avec Django. Nous nous
poserons les questions suivantes :
• Qu'allons- nous mettre comme URL dans l'attribut action ?
• Comment allons- nous gérer dans Django la réception des données du formulaire ?
• Comment gérer des données erronées du formulaire ?
• Comment réagir lorsque toutes les données du formulaire sont correctes ?
Vl
Q)
0L..
>-
UJ
N
..-!
0 SOMMAIRE
N
@ ~ Comment réaliser les formulaires en Django ?
......
..c ~ Installation de nos premiers formulaires dans Trombinoscoop
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Au chapitre précédent, nous avons vu ce qu'étaient les templates et les avons utilisés
dans la page de login de Trombinoscoop, avec un résultat au final assez sympathique.
Malheureusement, la page n'est pas vraiment opérationnelle. Si on clique sur le
bouton Se connecter, rien ne se passe. Nous allons maintenant ajouter le code pour
gérer ce formulaire et notamment préciser le contenu de l'attribut action .
def login(request) :
si formulaire envoyé
si paramètres pas ok
on affiche la page de login avec une erreur
sinon
on redirige vers la page d'accueil
sinon
on af fiche l a page de l ogin vierge de tou t e erreur
L'objet request
L:objet request, premier paramètre de toutes nos méthodes vi ews revêt une impor-
tance capitale. À vous de parfaitement le saisir ! Cet objet, de type Htt pReques t ,
nous permet d'accéder à toutes les informations encapsulées dans la requête HTTP,
dont l'ensemble des paramètres passés à la page web.
Pour accéder à ces paramètres, il suffit d'utiliser les objets GET et POST de l'objet
request, qui se comportent comme des dictionnaires. Par exemple, si l'on désire
connaître la valeur du paramètre ema i 1 de notre formulaire de login, on écrira :
Nous avons ajouté un import 0 , afin de pouvoir utiliser la fonction renvoyant une
redirection HTTP.
Pour savoir si le formulaire a été envoyé, on regarde dans l'objet request si la liste des
paramètres reçus est vide ou pas f). Si elle est vide, c'est qu'aucun paramètre n'a été
transmis, donc la page n'est pas appelée suite à la soumission de son formulaire. A
contrario, si la liste n'est pas vide, c'est que le formulaire a été soumis.
Dans le cas où le formulaire a été soumis, on vérifie que c'est bien les deux paramè-
tres emai 1 et password qui ont été transmis. Ceux-ci doivent se trouver dans le dic-
tionnaire GET de l'objet request e.
Si ce n'est pas le cas, on réaffiche la page login,
mais en passant une erreur au template O .
Ensuite, on récupère la valeur des deux paramètres 9 et on teste que le mot de passe
et le login sont bien ceux attendus (i). Si ce n'est pas le cas, on réaffiche la page de
login, avec une erreur f). Si tout va bien, on peut rediriger l'internaute vers la page
principale du site e.
Il reste le cas où le formulaire n'a pas été soumis. D ans ce cas, on affiche la page de
login vierge de tout message d'erreur G).
Vl
Q)
EXEMPLE 9.5 Trombinoscoop. Affichage du message d'erreur éventuel
0L..
>- <form action="login" method="POST">
U.J
{% if errer %}
N
.--! <P class="error">{{ errer }}</P>
0
N {% endif %}
@ Suite du code du formulaire._
...... </form>
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
form p.error {
margin -left: 160px;
color: #d23d24;
}
trombinoscoop
G:lur~I :
Mot de passe :
Voilà qui n'est déjà pas si mal ! Cependant, les sections suivantes vont vous montrer
qu'on peut faire ça plus proprement.
Vl
Q)
,_
0
>-
w
N
.--1
La bibliothèque forms de Django
0
N
@
L e but de Django est de vous simplifier la vie et d'automatiser les tâches courantes
~ afin que vous n'ayez pas à réinventer la roue.
.c
Cl'I
·c
>-
0..
0
u
Les formulaires Django -
CHAPITRE 9
Or, lorsqu'il s'agit de produire et gérer des formulaires, on est souvent amené à réécrire
des lignes de code identiques d'une fois sur l'autre. Django simplifie tout cela à l'aide de
sa bibliothèque forms, qui permet entre autres de:
• ne plus devoir écrire soi-même le HTML d'un formulaire. Tous les 1abe1 et
input sont ajoutés par Django.
• avoir une validation réalisée par Django, sans avoir à tout vérifier soi-même.
Django est, par exemple, capable de valider si une donnée encodée par un utilisa-
teur est bien une adresse courriel.
• réafficher le formulaire complété dans le cas où des erreurs auraient été détectées.
Pour l'instant, dans notre version de la page de login, lorsque les données sont
erronées, la page est réaffichée, mais toutes les données encodées par l'utilisateur
sont effacées. Qiand il n'y a que deux champs, ce n'est pas grave, mais dans le cas
d'un formulaire de plusieurs dizaines de champs, cela peut passablement énerver
le visiteur de votre site.
• convertir dans des types Python les données soumises à partir d'un formulaire. Tous
les paramètres qui accompagnent une requête HTTP sont textuels ; en consé-
quence, si un des champs d'un formulaire est numérique à la base (par exemple l'âge
du capitaine), pour être utilisable en Python, il va falloir convertir la donnée reçue
en un type numérique. L a bibliothèque fo rms de Django prend cela en charge.
l'autre de type CharField. Pour les deux, nous avons également spécifié le label du
champ, qui servira pour l'affichage.
Car ce dernier n'existe tout simplement pas ... Pour définir un champ de type « mot de passe», il faut
utiliser un CharFi el d et changer son rendu à l'aide de wi dget = forms . Password!nput f).
Nous avons pour l'instant laissé de côté tout ce qui concernait la validation du formu-
laire. Le but ici est d'observer la création automatique du formulaire dans le tem-
plate. Remplaçons le code du template par le suivant :
EXEMPLE 9.9 Trombinoscoop. Utilisation du LoginForm dans le template
Figure 9-2
Rendu de la page de login Trombinoscoop - Connexion
trombinoscoop
Comiel :
Mot de passe :
Vl
Q)
,_
0
>-
w Le résultat est identique au précédent! Et pour cause, Django a écrit exactement le
N
..-1
même HTML que nous (à quelques détails près) :
0
N
@
~
.c
OI
·c
>-
0..
0
u
Apprendre la programmation w eb avec Python et Django
Vl
Validation du formulaire
Q)
0L.. Voyons maintenant comment valider de notre formulaire, afin de retrouver le com-
>-
UJ
portement que nous avions auparavant.
N
.--! Les formulaires Django possèdent une méthode intitulée i s_val i d. Elle autorise des
0
N validations de base : vérifier que les champs obligatoires sont fournis, vérifier que le
@ courriel entré est bien une adresse valide, etc. La validation du mot de passe est en
.....
..c revanche un peu plus complexe ; il faudra la coder nous-mêmes. H eureusement,
en
ï:::: Django permet d'ajouter des validations propres.
>-
a.
0
u
Les formulaires Django . .
CHAPITRE 9
def login(request) :
#Teste si le formulaire a été envoyé
if request.method=="POST")
form = logi nForm(request.POST) f)
if form . is_valid(): E)
return HttpResponseRedirect('/welcome')
el se:
form = LoginForm() 0
return render_to_response ('login.html ', {'form': form})
Le début est le même : on teste si le formulaire a été soumis. Si ce n'est pas le cas, on
se crée un objet de type Logi nForm vierge qu'on passe au template Q . Si, au con-
traire, le formulaire a été soumis, on crée un objet de type Logi nForm en lui passant
cette fois-ci les données GET de la requête HTT P. On peut ensuite appliquer la
méthode i s_va 1 id E) qui va vérifier la validité de tous les champs du formulaire : si
le formulaire est valide, on redirige l'utilisateur, sinon on réaffiche la même page.
Voyons maintenant ce que cela donne dans un navigateur, après avoir entré
« pasbon » comme adresse de courriel et avoir omis de préciser un mot de passe.
trombinoscoop
Vl
Q) • Enter a valld e-mail address.
,_
0 Col.l'riel: ~
>-
w • This field is reqU1red.
N
.--1 Mot de passe :
0
N
@ •Uj,j:!:ii(,!M Creer un oomote
~
.c
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
On le voit, la gestion des erreurs est un peu différente de ce que nous avions dans
notre version manuelle du formulaire. En réalité, il faut l'avouer, elle est plus
complète : pour chaque champ erroné, un message d'erreur s'affiche (voire plusieurs,
le cas échéant). En outre, l'adresse de courriel encodée par l'utilisateur a été reprise,
alors que notre formulaire manuel remettait tous les champs à zéro.
EXEMPLE 9.12 Trombinoscoop. Code HTML produit par Django pour les messages d'erreur
Donc, dans nos CSS, nous pouvons écrire le code suivant, en remplacement des ins-
tructions CSS que nous avions destinées au sélecteur fo rm p . e r ro r :
Vl
EXEMPLE 9.13 Trombinoscoop. Présentation des messages d'erreur
Q)
0L.. ul.errorl i st {
>-
U.J margin- left : 160px ;
N
.--!
padding : O;
0 list- style - type: none;
N
color : #d23d24;
@
...... }
..c
en
ï::::
>-
a.
0
u
__________________________L_e_s_f_o_r_m_u_l_a_ir_e_s_D~j_a_n=
g_o_~
CHAPITRE 9 milm
Le résultat obtenu est maintenant le suivant.
Figure 9-4
Nouvel aspect Trombônoscoop - Connexion
des messages d'erreur
trombinoscoop
Co1..-riel : p_
as_bo_n_ _ _ _ _ _ _ __,
L.'-1
Mot de passe :
return cleaned_data f)
Nous redéfinissons donc la méthode cl ean Q. Tout d'abord, on appelle cette même
fonction au niveau de la classe parente (c'est le super qui s'en charge f)), car cette
dernière effectue des traitements qu'on aimerait ne pas devoir ré-implémenter.
Ensuite, on récupère la valeur<< nettoyée» des champs Q . Si les champs n'étaient pas
valides, les lignes cl eaned_data. get ne retourneraient rien.
On vérifie ensuite que les deux champs sont valides, en s'assurant que les lignes
cl eaned_data . get ont retourné quelque chose 0 - En effet, il ne sert à rien de véri-
fier que le courriel ou le mot de passe sont les bons, si les données ne satisfont déjà
pas les contrôles basiques.
Ensuite, on peut vérifier que courriel et mot de passe sont bien ceux attendus 9 . Si
ce n'est pas le cas, on retourne une erreur à l'aide de la méthode Python rai se(!).
C'est ainsi que Django exige que l'on procède; cela lui permet d'ajouter notre erreur
à la liste des erreurs du formulaire.
Figure 9-5
Ajout de la vérification TrombinoS<:oop - Connexion
Co11riel: [ [email protected] ~
Vl
Q)
Mot de passe :
,_
0
>- Ej%!.i§!M Créer un oompte
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Les formulaires Django . .
CHAPITRE 9
Enfin, pour terminer, on retourne les données nettoyées, car, ne l'oublions pas, cela
reste après tout le but premier de cette méthode O.
Ce code une fois ajouté, si on entre un courriel et un mot de passe qui, pris séparément,
sont valides, mais ne correspondent pas à ce qu'on attend, on obtient le résultat présenté à
la figure 9-5.
C'est exactement ce que l'on recherchait! Et on peut constater que Django a signalé
l'erreur au tout début du formulaire, avant le premier champ.
Vl
Q)
0L..
>-
U.J
N
T"'f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
10
Les modèles Django
L'objectif de ce chapitre est d'étudier comment mettre en place une base de données à l 'aide des
modèles Django et comment interagir avec elle. Plus précisément, nous allons apprendre à :
• décrire les données à enregistrer dans la base de données;
• créer la base de données;
• insérer des données dans la base de données ;
• accéder aux données pour ensuite les utiliser dans notre code.
Vl
Q)
0L..
>-
UJ
SOMMAIRE
N
..-!
0 ~ Réalisation de la base de données à la manière de Django
N
@ ~ Introduction aux modèles Django, version objet de la base de données sous-jacente
..... ~ Suite du projet Trombinoscoop
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Au chapitre précédent, nous avons appris à récupérer et utiliser les données d'un for-
mulaire, essentiellement pour la mise en place de notre page d'authentification.
Cette page souffre d'un grand défaut : la vérification de l'adresse de courriel et du
mot de passe est entièrement statique, ces deux données d'authentification étant ins-
crites directement dans le code Python. Il est donc très difficile d'ajouter de nou-
veaux utilisateurs. En réalité, un élément essentiel manque à notre application web :
une base de données qui permettrait d'enregistrer plusieurs utilisateurs avec toutes
leurs caractéristiques, et en particulier leur adresse courriel et leur mot de passe.
Vl
Q)
0L..
Création d'un premier modèle
>-
U.J Pour rappel, le diagramme de classes du modèle à implémenter était le suivant :
N
..-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
Fonction
+Intitulé
~tudiant Cursus
+Année o..• 1 +Intitulé
campus
Nom
+Adresse postale
Le modèle Personne
Démarrons progressivement et voyons d'abord comment s'occuper de l'objet
Personne à l'aide des modèles, sans se soucier des autres objets pour l'instant.
En Django, un modèle est une classe qui hérite de la classe Mode l fournie par Django.
On a généralement une classe de type Model par objet que l'on désire sauvegarder (ou
par table de la base de données). Dans notre cas, nous aurons donc un modèle
dénommé Personne. Ensuite, définir le modèle consiste essentiellement à lister les
champs qui le composent, avec leur type.
On regroupe généralement les modèles dans un fichier nommé mode l s . py. Créons
donc ce fichier dans Eclipse, au même niveau que vi ews . py et ajoutons le code
suivant:
EXEMPLE 10.1 Trombinoscoop. Définition d'un premier modèle pour l'objet Personne
C'est aussi simple que cela ! On importe la bibliothèque mode l s 0 , on crée une
classe Personne héritant de mode l s . Mode l f) et, pour terminer, on définit tous nos
champs en leur donnant un type.
Avec ces informations, Django est capable de créer la base de données adéquate.
Configuration
Auparavant, ilfaut toutefois déclarer l'application Trombinoscoop dans
setti ngs . py. C'est obligatoire dès que l'on utilise des modèles. Il faut donc ajouter la
ligne suivante :
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django .contrib.sites',
'django .contrib.messages',
'django .contrib.staticfiles',
'Trombinoscoop',
#Notez qu'il serait préférable de ne pas mettre de majuscule a un nom d'application
)
DATABASES = {
Vl
'default' : {
Q)
'ENGINE': 'django .db.backends.sqlite3',
0L.. 'NAME ' : os.path . join(PROJECT_ROOT, 'sqlite .db'),
>-
U.J 'USER ' : '' ,
N ' PASSWORD' : ' '
...-!
0 'HOST ' : ''
N
' PORT ' : ''
@ }
......
..c }
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
Comme vous pouvez le constater, le moteur de bases de données utilisé par Django
est SQI..,ite3, cela tombe bien. Oyant à l'emplacement, la partie que nous avons
modifiée demande à Django de créer la base de données dans le dossier du projet.
8
sm New
Go lnto
from
from
d j ango.shortcuts 1.111POrt render_
django.http import HttpResponse
ltl
[il
from dateeime impore dateeime
e copy from form.s import LoginForm
ltl ~ Pasœ
>C Deleœ def welcome (reques t ) :
œ reeurn render_ eo_ response ( 'velco~e
Ill Move.•.
ltl Reia~ ...
def login(request):
ltl
OO èa ~t. .. ~
if l en(request.GET) > 0 :
ltl lfl ci Export. . .
form e LoqinForm(request . GET)
ood t) Refresh FS if f orm.is_ valid():
Close Project return HttpResponseRedirect ( •,
'"b!'e ~ el" ed ProjeC'.s else :
return render_eo_response ( 'le
RLl1 As
Dl!bug As
Pro~As
Valida te
Team fù PyUnit
CompareWilli
Restore from Loail tistory .. .
PyOev
dj Ojango • CU&tom coovnand (manage.py ${custom_C01M1and})
Source Sync DB (manaqe.py syncdb)
Conf9,Jre Run Ojango Tests (manage.py œst)
Shel willi django eiviromient
Properties Alt+fnter
Vl Build WAR Pacl<age
Q)
create application (manage.py startapp)
[ --
,_
0
r 111:1 Remove Django Project Conlig
>-
w
N
.-1
0
N Au lancement de cette commande, Django part à la recherche de toutes les classes de
@ type Mode 1 et crée les tables correspondantes. À la console, on constate que Django
~
.c est bien en train de créer la base de données :
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Creating tables . . .
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table Trombinoscoop_personne
Django vous demande ensuite si vous souhaitez créer un superuser dans le système.
Faites-lui confiance et répondez: cliquez dans la console et tapez au clavier le mot
yes avant d'appuyer sur la touche Entrée . Il faut ensuite introduire un nom d'utilisa-
teur, une adresse de courriel et un mot de passe (deux fois). Cet utilisateur pourra
introduire des données de test dans les tables. Notez bien ces informations, elles vous
seront utiles par la suite.
Si tout se passe bien, la console indique ceci :
Vou just installed Django's auth system, which means you don't have any
superusers defined .
Would you l i ke to create one now? (yes/no) : yes
Username (leave blank to use 'pierre') : pierre
E-mail address : [email protected]
Password : azerty
Password (again) : azerty
Superuser created successfully .
Installing custom SQL ...
Installing indexes . ..
Installed 0 object(s) from 0 fixture(s)
Finished "( :\Documents and Settings\Pierre\Mes documents\Mes
projets\Trombinoscoop\manage . py syncdb" execution .
Vl
Q) Et voilà, la base de données est créée. En atteste le nouveau fichier sql i te. db qui se
0L.. trouve dans notre projet. E mpressons-nous de l'ouvrir à l'aide de l'outil SQ!.,ite
>-
UJ Database Browser (que nous avons présenté au chapitre 6).
N
.-f
0
N
EN PRATIQUE Si vous ne voyez pas sqlite.db dans Eclipse...
@
...... ... un petit rafraîchissement s'impose : appuyez sur FS et il apparaîtra .
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
Figure 10-3
Ouverture de la base ii·
fi• E<l1t
1.
View
.
·~
Help
•r•e ,, ' - . - .-- ..:;;;.,
de données avec
SQLite Database Browser ~ ~~ llC) im~ 6f rii im· []f ~ ~?
Oatabase Structt.re L arowse oata 1 Execute SQl.
Name 1Obiect 1Type 1Schema "'
è "dJango_site CREA . ..
_.. Trombinoscoop_persome
'"'""
table CREA ...
1 f·. td field 11teger PRIMARY KEY
! r"·mabirule fil!ld varchar(IO)
!i i
r. nom field varchar(30)
1 t"·prenom field varchar(30)
i t···date de naissance field date ;il
f ~... courr~I - field varchar(75)
11 ~...te!- füœ fil!ld varchar(20)
i
i
, ... tel mobie field varchar(20) ,...
! L.mot_de_passe field varchar(32)
f"'S~te_autolndex_aAJtn_permission_l index
j"·s~te_autolndex_auth~oup_permissions_! i'ldex
t"'auth_gro._.,_permissions_!eO 1<kSf index CREA ...
f"·auth_user _user_permissions_'103f60f index CREA ... jv
11 '
De nombreuses tables ont été créées alors qu'on s'attendait à en trouver une seule.
C'est normal, Django ajoute à la base de données des tables de travail dont il aura
besoin pour d'autres fonctionnalités du framework (nous en reparlerons dans les cha-
pitres suivants). Laissons donc de côté ces tables et concentrons-nous sur
Trombi noscoop_ personne en particulier. Tous les champs ont été créés conformé-
ment à nos desiderata. Un champ supplémentaire a cependant été ajouté: id. C'est
la clé primaire identifiant de manière unique chaque enregistrement. Comme nous
n'avons pas dit que le champ ma tri cule pouvait faire office de clé primaire, Django a
pris l'initiative d'en créer une. Finalement, pourquoi ne pas la laisser?
Comme un message correspond à une et une seule personne, nous avons ajouté un
champ Forei gnKey que nous avons nommé auteur et qui pointe vers la classe
Personne Q. Du côté de la classe Personne, il n'y a rien à ajouter. La relation devient
implicite.
Vl
Q)
0L..
La relation « ami » : relation n-n
>-
U.J Ajoutons maintenant la relation « ami » qui lie des personnes entre elles et qui est de
N
T"'f type « n-n » . Pour exprimer cette relation, il suffit d'ajouter un champ
0
N ManyToManyFi e 1d qui pointe vers la classe elle-même (self) f). Ce champ, nous le
@ nommons amis (au pluriel). Notez que nous avons ajouté le paramètre nul l=True
......
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
afin de rendre ce champ optionnel. On n'est pas obligé d'avoir au moins un ami : les
asociaux ne sont pas interdits sur notre site.
EXEMPLE 10.6 Trombinoscoop. Ajout des modèles Faculte, Campus, Fonction et Cursus
0L..
>-
U.J Les modèles Employé et Étudiant : héritage
N
T"'f
0 Il reste à définir les objets Employe et Etudiant. C'est très simple, il suffit de créer
N
@
deux nouveaux modèles qui héritent de la classe Personne, exactement comme dans
..... notre modèle conceptuel de données .
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Django sait convertir cette hiérarchie de classes en tables dans la base de données, en
ajoutant les liens nécessaires. En fait, il traduit le mécanisme d'héritage en une liaison
« 1-1 »au sens du relationnel: une clé étrangère reliée à la table Personne a été ajoutée
dans les tables Emp 1oyé et Étudiant. Qyand bien même le mécanisme d'héritage existe
entre les classes dans le « monde objet » et non entre les tables dans le « monde
relationnel», Django réussit à gérer la base de données relationnelle pour qu'elle tienne
compte de cet héritage. Chapeau bas ! Voici le code de nos deux modèles :
Lorsqu'on ré-exécute un Sync DB, la base de données existante n'est pas écrasée et recréée à zéro. Elle
est simplement mise à jour par l'ajout des tables et des champs manquants. Si entre-temps, un champ ou
une classe a été supprimé(e) du modèle, Sync DB ne les supprime pas de la base de données.
Pour avoir une base de données lavée de tout soupçon, il est donc toujours conseillé de la détruire (en
supprimant le fichier sq 1 i te . db) préalablement à l'exécution de la commande Sync DB. Attention,
dans ce cas on perd toutes les données déjà saisies dans la base !
0L.. L e code est assez explicite. Remarquez cependant que, lorsqu'on crée l'objet
>-
UJ Etudiant, il faut fournir en paramètre tous les champs qui n'ont pas été déclarés
N
..-! optionnels (à l'aide de null=True) .
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Suppression d'enregistrements
L e code suivant illustre la suppression d'un enregistrement O ou plusieurs f).
En revanche, si on veut récupérer tous les messages d'une personne, c'est un peu plus
subtil car dans la classe Personne, il n'y a aucun champ pour cela.
H eureusement, Django est là pour nous assister. Il crée automatiquement des attri-
buts permettant de parcourir les relations en sens inverse : ces attributs sont toujours
nommés en ajoutant _set au nom de la classe visée (écrit en minuscules). On peut
donc facilement récupérer tous les messages d'une Personne.
0L..
>-
UJ
N
...-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Figure 10-4
Page principale du site
d'administration des 4-- C 0 127.0.0.1:8000/ adm11/
bases de données Django administration ""lcome pÎ~FR Chang• pas mord 1 Log out
Site administration
~c e nt Action~
Pour l'obtenir, on doit créer un fichier admi n. py, au même niveau que nos autres
fichiers Python. Dedans, nous allons lister tous les modèles qui doivent être gérés par
le site d'administration.
admin .site.register(Faculte)
admin .site . register(Campus)
admin .site . register(Fonction)
admin .site . register(Cursus)
admin .site . register(Employe)
admin.site.register(Etudiant)
admin.site.register(Message)
Nous avons volontairement omis le modèle Personne (qui est une classe parent), car
nous allons toujours créer soit des étudiants, soit des employés (les classes enfants qui
seules donneront naissance à de véritables objets).
Ensuite, on configure u rl s . py afin qu'à une certaine URL corresponde le site
d'administration. Cela se fait en ajoutant ces quelques lignes :
EXEMPLE 10.10 Trombînoscoop. Contenu de urls.py
admin.autodiscover()
urlpatterns = patterns('',
('A$' , l ogi n) ,
('Alogin$', login),
( ' Awelcome$', welcome),
(' Aadmin/', include(admin.site.urls))
)
Vl
Q)
0L.. Si elle ne s'y trouve pas, il faut également ajouter l'application admi n dans les
>-
U.J INSTALLED_APPS du fichier de configuration de Django setti ngs . py :
N
..-!
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
INSTALLED_APPS = (
'django . contrib.auth',
'django . contrib.contenttypes',
'django . contrib.sessions',
'django . contrib.sites',
'django . contrib .messages ' ,
'django . contrib .staticfiles',
'Trombinoscoop',
'django . contrib . admin',
)
1DEFAULT_CONTENT_TYPE = 'text/html'
Figure 10-5
Page d'authentification
du site d'administration
.. - C X
Django administration
Usemame:
Password:
Figure 10-6
Liste des cursus encodés .. 1_ C X 1
0 Cursus
0 Cursus object
O Cursus obi ect
2 cursuss
Vl
Q)
,_
0
>-
w
N
.--1
0
Nous avons bien deux cursus, cependant ils s'affichent tous les deux avec le même
N intitulé« Cursus object » . Django ne sait pas quel attribut de l'objet cursus utiliser
@
~
lorsqu'il doit l'afficher.
.c
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
class Faculte(models.Model) :
# Définition des champs
def ~unicode~(self) :
return self.nom
class Message(models.Model) :
# Définition des champs
def ~unicode~(self) :
if len(self .contenu) > 20:
return self . contenu[:19] +
el se:
return self . contenu
Vl
Q)
Nous avons découvert le principe de la redéfinition de méthodes dans le chapitre
0L..
trois consacré à !'orienté objet en Python. _ uni code_ tout comme _ str_ associe
>-
UJ
une chaîne de caractères à l'objet. Django sait maintenant que les objets de type
N
.-f
0
Cu r sus doivent s'afficher en utilisant leur intitulé (pour autant que vous n'ayez pas
N
oublié de redémarrer le votre projet Django !) :
@
......
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
Figure 10-7
liste des cursus encodés
avec leur initulé C 0 127.0.0. I :8000/adrn11{Tromb1noscoop/0Jrsus/
Django administration l'klcome. p;erre Change pass>wrd/Log out
tlome Trombmoscoop Ci
O Cu~us
O Master en Histoire
O Mnster en Géographie
2 cursuss
Remarquez que pour la classe Message, notre fonction _ uni code_ est un peu plus
complexe. Elle retourne le contenu du message, tronqué et suivi de points de suspen-
sion s'il est trop long (supérieur à 20 caractères).
Vous pouvez ensuite créer des cursus, des facultés, des étudiants, etc.
Maintenant que nous sommes en mesure d'ajouter des données dans la base, nous
pouvons modifier notre procédure de login afin qu'elle fasse coïncider les données
encodées par l'utilisateur avec celles de la base de données.
Vl
Q)
Authentification utilisant la base de données
,_
0
>- Afin que notre authentification puisse s'effectuer à partir de la base de données, il
w
N
faut modifier le code et le charger de vérifier que l'adresse de courriel et le mot de
.--1
0 passe introduits sont corrects .
N
@
~
.c
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
EXEMPLE 10.12 Trombinoscoop. Validation du mot de passe et du courriel utilisant la base de données
return cleaned_data
Avec Django, deux lignes suffisent pour vérifier le mot de passe et le courriel en uti-
lisant la base de données (trois lignes avec l'import 0 ). La première cherche toute
personne dont le mot de passe et le courriel correspondent à ce qui a été entré dans le
formulaire f). La deuxième vérifie qu'il n'y a qu'un seul résultat E).
Les ModelForm
Nous avons vu au chapitre précédent que la classe Form de Django automatisait la
gestion des formulaires et, en particulier, la création du code HTML correspondant.
Django permet d'aller encore plus loin dans l'automatisation des formulaires, en
créant un formulaire sur la base d'un modèle. Cette fonctionnalité tire son existence
d'un constat pratique : dans les sites web, il existe souvent des formulaires qui servent
à créer un objet de la base de données et qui reprennent tous les champs de cet objet.
C'est typiquement le cas dans Trombinoscoop: la page de création de compte pos-
sède pratiquement tous les champs du modèle Etudiant ou Emp 1oye.
Les Model Form s'utilisent pratiquement de la même manière que les Form. Ils ajoutent
simplement une méthode save qui, une fois les données du formulaire validées, les
sauve dans la base de données.
Passons sans plus attendre à la réalisation de notre page de création de compte. D ans
un premier temps, nous n'allons permettre que la création d'un profil étudiant.
urlpatterns = patterns('',
('A$', login),
(' "l ogi n$' , l ogi n) ,
( ' Awelcome$', welcome),
(' Aregister$', register),
('Aadmin/', include(admin .site . urls))
)
Cette URL appelle la vue regi ster que nous définissons comme suit:
EXEMPLE 10.15 Trombinoscoop. Définition de la vue register
def register(request) :
if len(request.GET) > 0:
form = St udentProfileForm(reques t. GET)
if form . is_val i d() :
form.save(commit=True)
return HttpResponseRedirect ('/login')
el se :
return render_to_response ('login . html', {'form' : form})
el se :
form = StudentProfileForm()
return render_to_response ('user_profile.html ', {'form' : form})
Vl
La logique de gestion du formulaire est exactement la même que pour le formulaire
Q)
0L..
de login vu au chapitre précédent. La seule différence tient dans l'ajout de la ligne
>- form . save(commit=True) dans le cas où le formulaire est valide; cette instruction a
U.J
N
pour effet d'enregistrer dans la base de données les informations du formulaire et
..-!
0 donc de créer un nouvel étudiant. Une fois le nouvel utilisateur créé, on le redirige
N
@
vers la page de login où il pourra s'authentifier.
.....
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
{% block content %}
<hl>Création d'un compte</hl> (i)
<form action=" register " method="get"> e
{{ form . as_p }}
<P>
<input type="submit" value="Créer un compte" /> O
</P>
</form>
{% endblock %}
On observe quelques petits changements par rapport à notre page de login : le titre
de la page o, l'i d de la balise body f), la page de destination de l'attribut action e,
l'intitulé du bouton de soumission O et l'ajout d'un titre <hl>(!).
body#loginPage section#content {
position: absolute ;
top: lSOpx;
left : 50%;
Vl
Q)
width : SOOpx;
margin: 0 0 0 - 250px;
0L..
padding : O;
>-
U.J }
N
.--!
0
N Ce code ne s'applique qu'aux éléments section dont l'i d est content qui se trouvent
@ dans une balise body dont l'i d est 1ag i nPage. Or, nous venons de changer l'i d de la
......
..c balise body pour notre nouveau template. Comme le positionnement tel qu'écrit con-
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
vient aussi pour la page de création de compte, et sans doute pour les futures pages que
nous allons créer, nous allons appliquer ce même style à toutes les pages, à l'exception
de la position top que l'on va remonter un peu pour toutes les pages autres que celle du
login. Par la même occasion, nous allons également améliorer l'aspect du titre qu'on a
ajouté.
body section#content {
position : absolu t e ;
top : llOpx;
left: 50%;
width : SOOpx;
margin : 0 0 0 - 250px;
padding : O;
}
body#loginPage section#content {
top : lSOpx;
}
hl {
text -al i gn : center;
fon t -size : 22px;
margin : Opx 60px 30px 60px;
padding : 0 0 Spx O;
color : #3b5998;
border- bottom : lpx sol i d #3b5998;
}
Et voilà! Maintenant nous allons pouvoir tester notre nouvelle page ! Relancez le
projet; le résultat est le suivant lorsqu'on tape l'adresse http://localhost:8000/register.
Rentrez les informations comme Django vous force à le faire (rappelez-vous que c'est
lui qui valide le formulaire à sa manière). Avouons-le, le peu de code qu'il a fallu
écrire pour obtenir cette superbe page est impressionnant !
Vl
Q)
0L..
>-
UJ
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
Figure 10-8
Tromblnosooop - Cl'éalion d i.
Création d'un compte
Nom: 1Alexis
"'""""'' § erre
oaœdonoissanœ: G 983-06-16
Matrio.Jo: [1111111111
Cou-rM!I: [f;[email protected]
Telmobie: 10123456789
Farulœ: (Ëac~es~~
Am"": [
J
lêJfj§llUl3.iu!M
liste déroulante pour choisir le type de profil à créer; en fonction du choix de l'utili-
sateur, nous afficherons l'un ou l'autre formulaire.
Commençons par créer le formulaire basé sur le modèle Emp l oye.
def register(request) :
if len(request .GET) > 0 and ' profileType ' in request .GET: 4»
studentForm = StudentProfileForm(prefix="st")
employeeForm = EmployeeProfileForm(prefi x="em")
if request.GET['profileType'] == 'student': ~
studentForm = StudentProfileForm(request.GET, prefix="st")
i f studentForm.is_valid() : ~
student Form .save(commit=True)
return HttpResponseRedirect(' /login ')
elif request .GET['profilelype'] == 'employee' :
employeeForm = EmployeeProfileForm(request .GET, prefix="em" )
if employeeForm . is_valid() :
employeeForm .save(commit=True)
return HttpResponseRedirect('/login')
#Le formulaire envoyé n'est pas valide
return render_to_response('user_profile . html ' ,
{'studentForm' : studentForm ,
'employeeForm': employeeForm}) ~
Vl
Q) else: e
0L.. studentForm = StudentProfileForm(prefix="st")
>- employeeForm = EmployeeProfileForm(prefix="em")
U.J return render_to_response('user_profile . html ',
N
T"'f {'studentForm ': studentForm,
0
N 'employeeForm' : employeeForm})
@
.....
..c
en
ï::::
>-
a.
0
u
Les modèles Django
CHAPITRE 10
Ce code est un peu plus subtil et il comprend plusieurs petites astuces. La première,
c'est que nous utilisons un paramètre supplémentaire qui nous permet de savoir quel
formulaire a été envoyé. Ce paramètre s'appelle profi 1 eîype et nous devrons
l'ajouter dans notre template. Il peut prendre deux valeurs :
• student s'il s'agit du formulaire de création d'un profil étudiant ;
• emp 1oyee s'il s'agit du formulaire de création d'un profil employé.
À la première ligne, nous vérifions si au moins un formulaire a été soumis, en éva-
luant le nombre de paramètres reçus Q . On s'assure également qu'on a bien reçu le
paramètre profi 1eî ype.
Si aucun formulaire n'a été soumis f), c'est simple. On crée deux Mode 1 Form vierges
qu'on transmet à notre template. Jusque-là, c'est presque comme avant, si ce n'est
qu'on a deux formulaires et qu'on les préfixe. Comme les champs sont pour la plupart
communs aux deux types de personnes, le préfixage évite à Django de créer des id
qui portent le même nom, alors que ceux-ci doivent être uniques dans notre HTML.
Si un formulaire a été soumis, on regarde lequel. Si c'est le formulaire de création
d'étudiant 9 , on crée un Model Form étudiant qu'on initialise avec les données reçues
et un Mode 1Fo rm employé vierge. E nsuite, on vérifie si le formulaire étudiant est
valide Q . S'il l'est, tout va bien, on enregistre les données et on redirige l'utilisateur
vers la page de login. Sinon, on réaffiche la page de création de profil en passant en
paramètre les deux Mode 1 Form 9 .
On réalise exactement l'inverse si c'est le formulaire de création d'employé qui est
soumis.
<select id="profileîype">
<Option value="student" {%if studentForm . is_bound %} f)
selected="selected" {% endif %}>Étudiant</option>
<Option value="employee" {%if employeeForm . is_bound %}
selected="selected" {% endif %}>Employé</option>
</select>
</P>
</form>
Premier constat : nous avons trois formulaires, alors que nous nous attendions à n'en
définir que deux.
Le premier formulaire est là pour accueillir la liste déroulante Q . Ce n'est pas obliga-
toire, mais c'est plus facile du point de vue CSS. En plaçant la liste déroulante dans
un formulaire, les styles que nous avons déjà définis s'appliqueront. De toute façon,
ce formulaire ne possède ni bouton de soumission, ni attribut action .
Notre liste déroulante possède deux options, étudiant ou employé; c'est logique. Le
code {% if studentForm.is_bound %} selected="selected" {% endif %} f)
mérite en revanche une explication. Il permet de traiter le cas où un formulaire
soumis n'est pas valide : lorsque la page est réaffichée, la valeur précédemment
choisie par l'utilisateur est pré-sélectionnée dans la liste déroulante.
Vl
Q)
Ensuite, nous avons la définition de nos deux formulaires. Le code est similaire à ce
que nous avons vu précédemment, si ce n'est qu'un nouveau champ a été ajouté e :
le champ profi 1 eîype qui est de type hi dden . C'est lui qui nous indique lequel des
deux formulaires a été soumis. Et comme il s'agit d'un champ technique que l'utilisa-
teur de notre site n'a pas à voir, on le cache.
Un peu de dynamisme
Enfin, nous aimerions que, dynamiquement, lorsque l'utilisateur choisit un élément
dans la liste, le bon formulaire soit affiché et l'autre masqué.
Nous allons utiliser du jQyery pour cela, comme nous l'avons découvert au
chapitre 4. La première chose à réaliser consiste à ajouter une référence à la biblio-
thèque dans l'en-tête de la page HTML. Cela se fait dans le template base. html .
<head>
<title>Trombinoscoop - {% block title %}Bienvenue{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="/static/css/style.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1. 7.2 .min.js">
</script>
</head>
D ans le template user _profi 1e . html , insérons le code suivant, qui apporte le dyna-
misme voulu. Ce code est à ajouter dans le bloc content, par exemple au tout début,
juste avant la balise <hl> .
<Script type="text/javascript">
function displayRightForm () ~ {
if ($( ' #profileîype') .val() == 'student ' ) {
$('#employeeForm') . hide();
$('#studentForm') .show();
}
else {
Vl $('#studentForm') . hide() ;
Q)
$('#employeeForm') . show() ;
0L.. }
>-
U.J }
N
T"'f
$(document) . ready (displayRightForm); Q
0 $( ' #profileType') .change (displayRightForm); f)
N
</script>
@
......
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
On définit d'abord une fonction qui affiche et masque l'un ou l'autre des deux for-
mulaires en fonction de la valeur de la liste déroulante. 0
Cette fonction doit ensuite être appelée après deux événements :
• chaque fois que l'utilisateur change la valeur de la liste déroulante e;
• une première fois, au chargement de la page (via l'événement ready du
document) e.
Tout ce code nous permet finalement d'obtenir le magnifique résultat suivant:
Figure 10-9
On peut maintenant choisir
le type de compte que
l'on désire créer.
Nom:
Prenom:
Date de naissance:
MatrioJe:
_ _ _ _=i
Tel fixe:
Telmoble:
Motdepos$e:
611eau:
foroion: [ EJ
1 11
3M9 Ul!.l"'A
Vl
Q)
,_
0
Ai-je bien compris ?
>-
w • Pourquoi dans ce chapitre ne voit-on pas une seule ligne de SQI_, ? Ce langage
N
.--1 est-il utilisé par notre application web ?
0
N • Comment exprime-t-on les relations « 1-n », « n-n » et « 1-1 » dans les modèles ?
@
~ • À quoi servent les Model Forms ?
.c
OI
·c
>-
0..
0
u
11
Comprendre et utiliser les sessions
Ce chapitre va nous familiariser avec les sessions, qui servent à sauvegarder un contexte global
d 'interaction entre deux visites sur le serveur web. Les sessions fonctionnent grâce aux célèbres et tant
décriés cookies qui mémorisent les accès au serveur. Django a sa propre manière de répartir cette
mémoire entre le client et la base de données côté serveur. Le projet Trombinoscoop sera enrichi par
exemple par la mémorisation de l'identité du visiteur du site.
0L..
>-
UJ
SOMMAIRE
N
..-!
0 ~ Explication de la notion de session
N
@ ~ Explication et utilisation des cookies avec Django
......
..c ~ Prise en charge des sessions dans Trombinoscoop
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Les sessions fonctionnent grâce aux célèbres cookies, pour lesquels nous nous refu-
sons le moindre jeu de mot !
DÉFINITION Cookies
Les cookies sont des fichiers stockés par le navigateur dans le disque dur de l'internaute, lors de la visite
d'un site web. Ils sont créés à la demande du site visité et contiennent toute donnée que ce dernier juge
utile de sauvegarder. À chaque requête HTTP, le contenu du cookie est inclus dans l'en-tête de la requête
et peut être exploité par le serveur web pour adapter sa réponse en fonction de vos visites précédentes.
C'est grâce à ce mécanisme que l'on va attacher un contexte à chaque« session »de visite de notre site
web et passer de précieuses informations de pages en pages.
Configuration
Par défaut, les sessions sont activées dans Django. E n effet, dans le fichier
setti ngs. py, on trouve déjà les lignes suivantes 0 :
MIDDLEWARE_CLASSES = (
'django .middleware.common.CommonMiddleware',
'django.contrib.sessions . middleware.SessionMiddleware', 0
'django .middleware.csrf. CsrfViewMiddleware', # pour éviter des posts
# tiers malicieux
'django . contrib .auth.middleware .Authenticati onMiddleware' ,
'django . contrib .messages .middleware.MessageMiddleware',
)
INSTALLED_APPS = (
Vl
Q)
'django . contrib.auth',
'django . contrib.contenttypes',
0L..
'django.contrib.sessions' , 0
>-
U.J 'django . contrib.sites ' ,
N
T"'f
'django . contrib.messages' ,
0
N
'django . contrib .staticfiles',
@
' Trombinoscoop',
...... 'django . contrib .admin',
..c )
en
ï::::
>-
a.
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
Souvenez-vous : lorsque nous avons créé la base avec Sync DB, nous avons constaté
que Django créait de nombreuses tables supplémentaires. Il s'agit de celles qui sont
nécessaires à la sauvegarde des données de session.
def login(request) :
0L..
>-
UJ Enregistrement de l'utilisateur authentifié
N
.--!
0 Reprenons le code de notre vue l ogi n qui gère l'authentification d'un utilisateur, et
N
@ adaptons-le afin de sauvegarder l'identité du visiteur authentifié.
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
def login(request) :
#Teste si le formulaire a été envoyé
if request .method=="POST" :
form = LoginForm(request . POST)
if form . is_valid() :
user_email = form.cleaned_data['email'] O
logged_user = Personne.objects.get(courriel=user_email) f)
request.session['logged_user_id'] = logged_user.id e
return HttpResponseRedirect ('/welcome')
el se:
form = LoginForm()
return render_to_response ('login.html ' , {'form' : form})
Seules trois lignes de code ont été ajoutées (mis à part l'import). La première récu-
père à partir du formulaire l'adresse de courriel que l'utilisateur a introduite Q . On
utilise ensuite cette adresse de courriel pour récupérer dans la base de données l'objet
Personne qui possède cette adresse f). On sauvegarde ensuite dans la session l'i d de
cette personne. Ensuite seulement, on fait la redirection vers la page d'accueil.
def welcome(request) :
if 'logged_user_i d' in request . session : O
logged_user_id = request.session[ ' logged_user_id'] f)
logged_user = Personne.objects . get(id=logged_user_id) Q
return render_to_response('welcome . html',
Vl
Q) .,. {'logged_user' : logged_user}) ~
0L.. el se :
>- return HttpResponseRedirect('/login') f)
UJ
N
.-!
0 On vérifie d'abord qu'on a bien un i d d'utilisateur dans la session Q. Si oui, c'est que
N
@ le visiteur de notre site est authentifié f) ; on le récupère alors dans la base de
......
..c données e,puis on appelle le template we lcome . html en lui passant en paramètre
en
ï::::
>-
a.
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
{% extends "base.html" %} e
{% block title %}Accueil{% endblock %}
{% block content %}
<p>{{ l ogged_user.prenom }} {{ l ogged_user.nom }}, O
bienvenue sur Trombinoscoop !</P>
{% endblock %}
Testons maintenant notre nouvelle page d'accueil. Lorsqu'on n'est pas authentifié, on
est redirigé vers la page de login. Si l'authentification se passe correctement, on
obtient le résultat suivant :
Figure 11-1
La nouvelle page d'accueil Trombinoscoop - Ac:cuei
personnalisée +- C Q 127.0.0.1:8000/welcome
trombinoscoop
Pierre Alexis, blenv~e sur TrombinoSCOOj) !
Vl
Q)
,_
0
>-
w
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Les navigateurs récents possèdent généralement des outils pour visionner le contenu des cookies. C'est
le cas par exemple de Google Chrome : Outils > Outils de développement > Cookies.
trombinoscoop
Resouroes 1 <:) Networ1<
YLJ f rames Value liTTP S
"' I Oatabases
"' 1 lndexedDB
"' Local Stora~
"' Session Stora~
C X 0
,_
0 Protection des pages privées
>-
w
N Maintenant que nous savons vérifier si un utilisateur est authentifié, nous allons pou-
.-1
0 voir protéger toutes nos pages privées. Plutôt que de dupliquer le code de la vue
N
@ we l corne, plaçons-le dans une fonction dont le rôle sera également de récupérer, le cas
~ échéant, l'utilisateur authentifié de la base de données. Nommons la fonction
.c
OI
·c get_ l ogged_user_ from_ request et insérons-la dans le fichier vi ews . py.
>-
0..
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
def get_logged_user_from_request(request):
if 'logged_user_id' in request .session : O
logged_user_id = request.session['logged_user_id ']
# On cherche un etudi ant
i f len(Etudiant .objects . f ilter(id=logged_user_i d)) 1: 9
return Etudiant .objects . get(id=logged_user_id)
# On cherche un Employe
elif len(Employe . objects .fil t er(i d=logged_user_id)) 1: O
return Employe . objects .get(id=logged_user_id)
# Si on n'a rien trouve
el se:
return None 9
el se :
retu rn None f)
def welcome(request) :
logged_user = get_l ogged_user_from_request(request)
i f logged_user :
return render_to_response('welcome . html',
{'logged_user' : logged_user})
el se :
return Ht tpResponseRedirect ('/login')
0L..
>-
U.J
N
..-!
0
Amélioration de notre page d'accueil
N
@ Pour l'instant, notre page d'accueil ne ressemble pas vraiment au wireframe que nous
...... avions conçu au départ.
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Vers Io~
d'offi~ d'un
profil
. ·~
'
©J (Q} 1
htrp://www tf'<>ml>1.nos<oop.com
1 Pl
Vuslo~de
ŒD
Pierre Alexis (Voir le pl'Ofil ) ( Modifi« le pt'Ofil ) - - 1• modificotio" du
09
Étudio"t ~ dwxibiie du MQStu ~ mothémotique profil
122~1 Bllbig:
~MSlYfat llca!DI
)- - ... Verslo~
,. d'ajout d'un ami
Personnalisation de la bannière
Commençons par nous occuper de la bannière qui doit contenir les données de l'uti-
lisateur connecté. Nous aurons besoin de savoir ce qu'est l'utilisateur connecté : un
Vl
Q)
étudiant ou un employé. Nous pourrions vérifier le type de l'objet 1 ogged_u se r passé
,_
0 au template. Malheureusement, ce n'est pas possible, les templates n'offrant pas
>-
w d'instruction pour connaître le type exact d'un objet P ython.
N
.--1 Le plus propre est donc d'ajouter un attribut à la classe Personne, qu'on surcharge
0
N dans les classes Étudiant et Emp 1 oyé pour retourner le bon type.
@
~
.c
Cl'I
·c
>-
0..
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
class Employe(Personne) :
# Autres champs
type_de_personne = 'employee'
class Etudiant(Personne) :
# Autres champs
type_de_personne = 'student'
Nous pouvons maintenant remplir notre bannière. Celle-ci n'étant plus juste une
simple et triste bannière vide comme pour la page de login, nous allons pour la pre-
mière fois redéfinir le bloc headerContent. Voici le code que nous avons placé dans le
template we 1 corne. htm 1 :
{% block headerContent %}
<p id="name">{{ logged_user . prenom }} {{ logged_user . nom }}</p>
<p id="function">
{%if logged_user . type_de_personne == 'student' %}
Étudiant en
{% if logged_user . annee == 1 %}
{{ l ogged_user . annee }}ère
{% else %}
{{ logged_user . annee }}ème
{% endif %}
{{ logged_user . cursus . intitule }}
{% else %}
{{ logged_user . fonction . intitule lcapfirst }}
Vl
Q)
dans la faculté {{ logged_user . faculte }}
0L.. {% endif %}
>- </p>
UJ <p id="profilelinks">
N
.-f <a href="???" class="buttonlink">Voir le profi l</a>
0 <a href="???" class="buttonlink">Modifier le profil</a>
N
@ </P>
...... {% endblock %}
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
body#welcomePage header {
background: #3b5998 url( ' .. /img/shortlogo . png') no- repeat 20px 25px;
color : #FFFFFF;
}
a . buttonlink {
border-style : solid;
border-width : lpx;
border -color : #d9dfea #OelfSb #OelfSb #d9dfea ;
background -color : #3b5998 ;
color : #FFFFFF;
padding : 2px lSpx 3px lSpx;
text-align: center;
text-decoration: none;
}
Vl
Q) Notez que nous avons changé le logo pour un plus petit, shortlogo . png, qui prend
0L.. moins de place et reprend uniquement la première lettre de Trombinoscoop.
>-
UJ
Sauvegardons et relançons le serveur web. Le résultat est le suivant :
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
Figure 11-4
la page d'accueil Tromblnoscoop - ACOJ<!Œ
et sa bannière
{% block content %}
<section id="messagelist">
test
</section>
<section id="friendlist">
test
</section>
{% endblock %}
Vl
Q) Au niveau des CSS, nous allons placer les deux sections l'une à côté de l'autre, en leur
,_
0 donnant une largeur bien précise. Au passage, nous allons, pour cette page d'accueil,
>-
w agrandir la largeur de l'élément accueillant le contenu. Nous avons besoin de plus de
N
.--1
place que sur les autres pages. Le code CSS que nous ajoutons est le suivant :
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
body#welcomePage section#content {
width: 800px;
margi n: 0 0 0 -400px;
}
body#welcomePage section#messagelist {
position: absolute;
width: 600px;
background -color: red;
}
body#welcomePage section#friendlist {
position: absolute;
width: 200px;
right: O;
background -color : yellow;
}
Notez que nous avons ajouté une couleur de fond très voyante à nos deux sections. Rassurez-vous, ce
n'est que temporaire! Cela aidera à repérer facilement les sections et à voir où elles se positionnent
exactement.
Figure 11-5
Tl'ombinoscoop - A«uell
Positionnement de la liste des
messages et de la liste des amis +- -+ C Q 127 0 0 1
· · · :soootwe1come
m-----------------lt.est
Vl
Q)
,_
0
>-
w
N
.--1
0
N
@
~
.c
OI
·c
>-
0..
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
<section id="messagelist">
<form action="welcome" method="get" class=" inlineForm">
<label for="newMessagelnput">Publier un message : </label>
<input type="text" name="newMessage" i d="newMessagelnput" />
<input type="submit" value="Publ i er" />
</form>
<Ul>
{% for message in friendMessages %}
<li>
<P>
<a href="???">{{ message . auteur . prenom}}
{{message . auteur . nom }}</a> dit :
</P>
<p>{{ message . contenu }}</P>
</li>
{% endfor %}
</ul>
</section>
Vl
Q)
EN PRATIQUE Pourquoi ne pas utiliser logged_user déjà présente dans le template ?
0L..
>-
U.J
Tout simplement car récupérer l'ensemble des messages des amis de l'utilisateur authentifié demande
N une requête trop compliquée qu'il est impossible d'exprimer avec Django seul. Ce n'est par ailleurs pas
T"'f
0 du tout le rôle des templates d'effectuer des traitements aussi complexes. On va donc effectuer cette
N requête dans la vue, en présence des méthodes de filtrage du modèle.
@
......
..c.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
La vue sera modifiée comme suit de sorte à initialiser la liste des messages :
def welcome(request) :
logged_user = get_logged_user_from_request(request)
i f not logged_user is None:
friendMessages = Message.objects.filter
(auteur~amis=logged_user).order_by('-date_de_publication')
Une ligne de code nous suffit à récupérer les messages voulus. Pour récupérer
l'ensemble des messages des amis de l'utilisateur authentifié, on part de l'objet
Message . On y applique un fùtre assez simple qui signifie « tous les messages dont un
des amis de l'auteur du message est l'utilisateur authentifié». Le résultat retourné par
le filtre est ensuite trié par ordre chronologique inverse (le message le plus récent doit
apparaître en premier) et envoyé au template.
Ce filtre sera transformé par Django en une requête SQ!., plutôt complexe et effi-
cace, que VOICI :
0L.. Si nous avions dû écrire cette requête nous-mêmes, il est plus que probable qu'après
>-
UJ une très longue réflexion, nous serions arrivés exactement au même résultat ; c'est la
N
.-f plus simple et la plus efficace pour récupérer les messages désirés .
0
N
On voit ici encore toute la puissance du framework Django (on ne s'en lasse pas !),
@
...... capable de transformer du code Python simple en instructions SQ!., complexes et qui
..c
en ne perdent rien en performance.
ï::::
>-
a.
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
La vue étant mise à jour, nous pouvons lancer 1'application. Le résultat est le suivant :
Figure 111
Première version de la liste
des messages ~
t
Trombinoscoop - Accueil
C Q -
127.0.0.1:8000/welcome
Pierre Alexis
Étucli.ant en l~e Mà5ta' en Geogtaplilt'
~~
1- D X
form.inlineForm label {
display: inline;
fl oat : none;
padding: O;
}
form.inlineForm input[type="text"] {
display : inline- block;
width: lSOpx;
}
form.inlineForm input[type="submit"] {
margin : O;
}
Vl
Q)
,_
0 section#messagelist ul {
>- margin : 20px 0 0 O;
w
N
list-style: none ;
.--1 padding: O;
0
N }
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
section#messagelist ul li {
ma rgin -bottom : l Opx;
}
section#messagelist ul li p {
margin : 8px 0 0 O;
}
Nous avons créé une nouvelle classe de formulaire, in 1 i neForm, pour laquelle tous les
champs doivent être placés sur une seule ligne. Cette classe annule les styles génériques
que nous avions définis pour tous les formulaires basés sur un affichage de type bloc.
Les règles CSS qui suivent modifient légèrement l'aspect de la liste, notamment en
supprimant la puce. Notre page d'accueil ressemble maintenant à ceci :
Figure 11-7
Version définitive de la liste
des messages +- -+
t
Trombinoscoop - Accueil
C -
~ 127.0.0.1:8000/welCOme
Pierre Alexis
Étudiant en lbe Moster en Geoo1dPhli'
~~
1- D X
test:
Publier 1.1"'1 message : r
Xavier Devos d t :
Ce site est vrament gérial 1:~
~dt :
Vl
Q)
<section i d="fri endli st">
<P class="title">Mes amis</P>
,_
0
>- <P><a href="???" class="buttonlink">Ajouter</a></P>
w <Ul>
N
..-1 {% for ami in logged_user .amis. all %}
0 <li><a href="???">{{ ami . prenom}} {{ ami . nom }}</a></li>
N
@ {% endfor %}
~ </ul>
.c </sect ion>
Cl'I
·c
>-
0..
0
u
Comprendre et utiliser les sessions
CHAPITRE 11
Nous modifions également nos CSS pour améliorer le rendu de cette liste:
body#welcomePage section#friendlist {
position : absolute;
width: 180px;
right: O;
padding: lOpx;
background -color: #DCEOED;
}
section#friendlist p. t i t le {
font -size : 22px;
color : #3b5998;
border- bottom: lpx solid #3b5998;
margin : 0 0 20px O;
}
section#friendlist ul {
margin : 20px 0 0 O;
list-style: none ;
padding : O;
}
section#friendlist ul li {
margin : 0 0 Spx O;
}
Et voilà, notre liste est terminée! E t avec elle, c'est tout l'aspect de la page d'accueil
qui est achevé et en de bonnes mains.
Figure 11-8
Rendu final de la page d'accueil
+- -+
t
Trombl- - Aa:Uell
C -
~ 127.0.0.1:8000/wefcome
Pierre Alexis
Etudiant en iere Mastrr en Géographie
1- D
Vl
Publier..., message: L =mJllD Mes amis
Q)
~ clt:
,_
0
Ce site ~tvramentgérial ! : ~
>-
w Huguoslle..ndt:
Ced estmani;r-emier messages:-)
N
.--1 ):avier Devœ dt :
0 Ced est men premier message " .....
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Pas mal hein ! Si l'apparence est définitive, il nous reste cependant une dernière fonc-
tionnalité à implémenter.
def welcome(request) :
logged_user = get_logged_user_from_request (request)
if not logged_user is None :
if 'newMessage' in request.GET and request.GET['newMessage'] != ''·
newMessage = Message(auteur=logged_user,
contenu=request.GET['newMessage'],
date_de_publication = datetime.date.today())
newMessage.save()
On vérifie tout simplement si un nouveau message est passé en paramètre. Si tel est
le cas, on crée un nouvel objet Message en initialisant chacun de ses champs pour
ensuite le sauver dans la base de données.
Cette fois, notre page d'accueil est terminée ! Nous pouvons la définir comme page par
défaut de notre site (en d'autres mots, celle qui s'affiche lorsque l'utilisateur n'entre pas
de nom de page dans l'URL), en modifiant le fichier u r l s. py comme suit :
Vl
Q)
urlpatterns = patterns('',
('A$', welcome), #au lieu de login
('A1ogi n$' , 1ogi n),
('Awelcome$', welcome) ,
('Aregister$', register),
('Aadmin/', include(admin.s i te.u rls))
)
Vl
Q)
0L..
>-
U.J
N
.--!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
12
En finir avec Trombinoscoop
Finalisons notre projet de développement web en réalisant les derniers wireframes. Nous
appliquerons pour cela tout ce que nous avons appris dans les précédents chapitres.
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@ SOMMAIRE
......
..c ~ Finition de Trombinoscoop
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Aux chapitres précédents, nous avons étudié les principales composantes du fra-
mework et leur étude a été l'occasion de réaliser les premières pages du site Trombi-
noscoop. Ici, nous allons réaliser les pages manquantes. Rassurez-vous, vous avez
déjà vu tous les outils dont nous avons besoin.
Voici un petit récapitulatif de ce que nous avons déjà terminé :
• la page d'authentification;
• la page de création de compte ;
• la page d'accueil.
Il nous reste donc à réaliser :
• la page d'ajout d'un ami;
• la page de visualisation d'un profil;
• la page de modification d'un compte.
Figure 12-1
Page d'ajout d'un ami
Ajoute r un ami
Vl ~~
Q)
Retour è Io poge
,_
0 doeeoeil
>-
w
N
.--1 Ajout d'un formulaire dans forms.py
0
N
@
Nous allons utiliser un formulaire Django issu de la bibliothèque forms (voir
~ chapitre 10). C'est dans le fichier forms . py que nous ajoutons le code suivant:
.c
Cl'I
·c
>-
0..
0
u
En finir avec Trombinoscoop
CHAPITRE 12
def add_friend(request) :
logged_user = get_logged_user_from_request(request)
if logged_user :
#Teste si le formulaire a été envoyé
if len(request .GET) > 0:
form = AddFri endForm(request.GET)
if form.is_val i d():
new_friend_email = form . cleaned_data[ 'email ']
newFriend = Personne.objects . get(courriel =new_frien d_email)
logged_user.amis .add(newFriend)
logged_user.save()
return HttpResponseRed i rect('/welcome')
el se :
return render_to_response ('addFriend .html' , {'form' : form})
#Le formulaire n'a pas été envoyé
el se:
form = AddFri endForm()
Vl
Q) return render_to_response ('addFriend . html ', {'form' : form} )
0L.. el se :
>- return HttpResponseRedirect('/login')
UJ
N
..-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
{% block content %}
<hl>Ajout d' un ami</hl>
<form action="addFriend" method="get">
{{ form . as_p }}
<P>
<input type="submit" value="Ajouter" />
</p>
</form>
{% endblock %}
urlpatterns = patterns('',
('A$', welcome), #au lieu de login
('Al ogi n$' , l ogi n),
('Awelcome$', welcome) ,
('Aregister$' , register),
('AaddFriend$', add_friend),
( ' Aadmin/', include(admi n.site.urls))
)
Figure 12-2
Page d'ajout d'un ami ._ C C 127.0.0.1 :8000/addFrlen<l?emal=ncolas
trombinoscoop
Ajout d'un ami
Figure 12-3
Page d'affichage d'un profil
©@ http://- .tronlb•nosœop.eom
1 Pl
.
l>ogoCI
Affichage d'un profil
Nom : Alvcis
Prénom : Pierre
Motncule : 01030405
Courriel : [email protected]
Foculté : Scowces
Vl
Q)
( !«tour )
,_
0
>-
w
N
.--1
0
...
Reto..- à Io poge
N doecueil
@
~ Cette page est assez triviale : il suffit d'ajouter un template qui reçoit en paramètre
.c
OI
·c
l'employé ou l'étudiant à afficher et d'afficher l'ensemble des champs du modèle.
>-
0..
0
u
Apprendre la programmation web avec Python et Django
{% block content %}
<hl>Affichage d'un profil</hl>
<dl class="fieldlist">
<dt>Nom :</dt>
<dd>{{ user_to_show . nom }}</dd>
<dt>Prénom :</dt>
<dd>{{ user_to_show . prenom }}</dd>
<dt>Date de naissance : </dt>
<dd>{{ user_t o_show.date_de_nai ssance }}</dd>
<dt>Matricul e :</dt >
<dd>{{ user_t o_show.matricul e }}</dd>
<dt>Courriel :</dt>
<dd>{{ user_to_show . courriel }}</dd>
<dt>Tél . fixe :</dt>
<dd>{{ user_to_show . tel _fixe }}</dd>
<dt>Tél . mobile :</dt>
<dd>{{ user_to_show.tel_mobile }}</dd>
<dt>Faculté :</dt>
<dd>{{ user_to_show.faculte . nom }}</dd>
{%if user_to_show . type_de_personne == "student" %}
<dt>Cursus :</dt>
<dd>{{ user_t o_show.cursus.inti tule }}</dd>
<dt>Année :</dt>
<dd>{{ user_to_show . annee }}</dd>
{% elif user_to_show . type_de_personne == "employee" %}
<dt>Bureau :</dt>
<dd>{{ user_to_show . bureau }}</dd>
<dt>Campus :</dt>
<dd>{{ user_to_show . campus . nom }}</dd>
<dt>Fonction :</dt>
Vl <dd>{{ user_to_show . fonction . intitule }}</dd>
Q)
{% endif %}
0L.. </dl>
>-
UJ <P id="showProfileNavigati onBut tons">
N
T"'f
<a href="welcome" class="buttonlink">Retour</a>
0
N
</P>
{% endblock %}
@
......
..c
en
ï::::
>-
a.
0
u
En finir avec Trombinoscoop
CHAPITRE 12
Le contenu est un peu verbeux, mais très simple à comprendre. L'affichage de toutes
les informations de l'utilisateur se base sur l'instruction H TML « liste de
définitions » (balise <dl>). Celle-ci fait correspondre à un élément sa définition, ce
qui correspond tout à fait à l'usage que l'on veut en faire. L'aspect de cette liste sera
amélioré dans les CSS.
def show_profile(request) :
logged_user = get_logged_user_from_request (request)
if logged_user : 0
# Teste si le paramètre attendu est bien passé
if 'userToShow' in request .GET and request .GET['userToShow'] != '' : f)
results = Personne . objects . filter(id=request .GET['userToShow']) E)
if len(results) == 1:
if Etudiant.objects .filter(id =request . GET['userToShow']):
user_to_show = Etudiant . objects . get(id=request . GET['userToShow']) f)
el se :
user_to_show = Employe .objects . get(id=request .GET['userToShow']) f)
return render_to_response ( ' show_profi le.ht ml ',
-. {'user_to_show' : user_to_show}) 0
el se:
return render_to_response ( ' show_profi le.ht ml ',
{'user_to_show' : logged_user}) 0
# Le paramètre n'a pas été trouvé
el se:
return render_to_response ('show_profile . html',
-. {'user_to_show': logged_user})
el se:
return HttpResponseRedirect('/login')
On vérifie d'abord qu'un utilisateur est authentifié 0 , comme sur toutes nos
pages« privées». Ensuite, on vérifie que l'i d de la personne dont on veut voir le profil
est bien passé en paramètre f) et on recherche l'enregistrement correspondant dans la
base de données E). En cas d'échec, on affiche le profù de l'utilisateur authentifié à la
Vl
Q)
place O . Ainsi, il n'y a pas de message d'erreur à gérer dans le template.
0L.. En revanche, si tout se passe pour le mieux, on cherche si la personne à afficher est
>-
U.J un étudiant ou un employé 9 et on extrait de la base de données le bon objet. On
N
T"'f appelle ensuite le template en passant en paramètre l'étudiant ou l'employé Q .
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
urlpatterns = patterns('',
('A$', welcome), #au lieu de login
('Alogin$', login),
( ' Awelcome$', welcome),
( ' Aregister$', regi ster),
( ' AaddFriend$', add_friend),
('AshowProfile$', show_profile) ,
( ' Aadmin/', include(admin .site . urls))
)
dl.fieldlist dt {
display: block;
width : 250px;
float : left;
text-align : right;
padding : 0 lOpx 0 O;
font -weight : bold;
}
dl .fieldlist dd {
display : block;
width : 450px;
padding : Opx;
margin : 0 0 lOpx O;
}
p#showProfileNavigationButtons {
margin : 20px 0 0 260px;
}
Vl
Q)
1
UJ
Ajout des liens dans la page d'accueil
~ Dernier point, mais non des moindres, n'oubliez pas de corriger sur la page d'accueil
~ tous les liens qui devraient pointer vers la nouvelle page d'affichage d'un profil. Il
@ s'agit de tous ceux qui entourent un nom (dans la liste des amis et dans la liste des
.:!: messages) et qui permettent à l'utilisateur, dès qu'il voit le nom d'une personne, de
.gi cliquer dessus et de voir son profil.
>-
a.
0
u
En finir avec Trombinoscoop
CHAPITRE 12
Il s'agit donc de modifier les lignes suivantes dans wel come. html
EXEMPLE 12.10 Trombinoscoop. lignes modifiées dans welcome.html
<li>
<P><a href=" showProfil e?userToShow={{ message . auteur . id }}">{ {
message.aute ur.prenom }} {{ message.auteur . nom }}</a> dit :</p>
<P>{{ message.contenu }}</p>
</li>
<Ul>
{%for ami in logged_user . amis . all %}
<li><a href=" showProfile?userToShow={{ ami . id}} ">{{ ami . prenom}} {{ami .nom
}}</a></l i>
{% endfor %}
</Ul>
Et voilà, notre page exposant le profil d'un utilisateur de notre site est prête. Le
rendu en est le suivant :
Figure 12-4 I- CJ X
Trombinoocoop - Affidlage d 1lll
Page d'affichage d'un profil
~ C ~ 127.0.0.1:8000/showProfile?userToShow:4
trombinoscoop
Affichage d 'un profil
Nom : Gatti
Prénom : Nicolas
Date de naisr.anœ : Feb. 13, 1973
Mab'icule: : 2222221222
Courriel : [email protected]
,_
0 Faculté: Fao.ftê de$ Soentes:
>-
w
C.U:rs:us : Master en Gécq-aphie
Annêe: 2
N
.--1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure 12-5
Wireframe de la page -
de modification du profil
@J@ ht tp.//www.tromb•1'0SGOOp.com
1 Pl
l>ogoCI
Modif ication de. mon profil
Nom : !Alexis 1
Prénom : \Pierre 1
Dote de naissance : 114/08/1902 1
Motrieule : jOt030405 1
Courriel : [email protected] 1
...
o
Retoor la pcl9e
<faccueil
{% block content %}
<hl>Modification de mon profil</hl>
<form action="modifyProfile" method="get">
{{ form. as_p }}
<P>
<input type="submit" value="Modifier" />
</P>
</form>
{% endblock %}
def modify_profile(request) :
logged_user = get_logged_user_from_request(request)
if logged_user :
if len(request.GET) > 0:
if type(logged_user) == Etudiant:
form = StudentProfileForm(request.GET , instance=logged_user)
el se:
form = EmployeeProfileForm(request.GET, instance=logged_user)
if form . is_valid():
form .save(commit=True)
return HttpResponseRedirect('/welcome')
el se:
return render_to_response ('modify_profile.html', {'form' : form})
el se:
if type(logged_user) == Etudiant:
form = StudentProfileForm( instance=logged_user)
el se:
Vl
Q) form = EmployeeProfileForm(instance=logged_user)
0L.. return render_to_response ('modify_profile . html', {'form' : form})
>- el se :
UJ
return HttpResponseRedirect('/login')
N
..-!
0
N
La structure de cette vue est assez standard. Petite nouveauté cependant : toutes les
@
..... initialisations des Mode 1 Form se font en passant en paramètre la personne dont on
..c
en désire modifier le profil (en l'occurrence, l'utilisateur authentifié). Si on omet de pré-
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
ciser ce paramètre, les Model Form ne sauront pas qu'il faut modifier un objet existant
de la base de données et vont en ajouter un nouveau, créant ainsi un doublon altéré.
urlpatterns = patterns('',
('A$', welcome), #au lieu de login
('Alogin$', login),
( ' Awelcome$', welcome),
( ' Aregister$', regi ster),
( ' AaddFriend$', add_friend),
( ' AshowProfile$ ', show_profile),
( ' AmodifyProfile$', modify_profile),
( ' Aadmin/', include(admin .site . urls))
)
<P id="profilelinks">
<a href="showProfile?userToShow={{ logged_user . id }}" class="buttonlink">Voir
le profil</a>
<a href="modifyProfile " class="button link">Modifier le profil </a>
</P>
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
En finir avec Trombinoscoop
CHAPITRE 12
Figure 12-6
Page de modification du profil r rombinoscoop- ModifiC211W
+- C ~ 127.0.0.1:8000/modfyProfle
trombinoscoop
Modification de mon profil
Nom: 1Devos
Prenom: ~~-
avi-e·_
r --------~
Date de naissance: j 1984-06-12
Ma~~= [0123456789
CCMSriel: [email protected]
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
13
Des sites web encore plus
dynamiques avec Ajax
Ce chapitre va se pencher sur la technologie Ajax qui permet au client de solliciter le serveur sans
quitter la page actuellement active de son côté. Le résultat du serveur viendra juste s'insérer dans la
page client courante sans qu'il Jaille entièrement la remplacer par une autre. C'est du javaScript
s'exécutant côté client qui va se charger de réaliser la connexion avec le serveur, la récupération des
informations et leur insertion dans la page client courante. L'interaction sera dite asynchrone car,
lorsque le client envoie la requête, il n'est pas contraint d'attendre la réponse du serveur pour
poursuivre sa tâche.
Vl
Q)
0L..
>- SOMMAIRE
U.J
N ~ Présentation de la technologie Ajax
..-!
0
N ~ Discussion sur la répartition de la partie « programme » du site web entre le client et le serveur
@ ~ Mise en place de solutions Ajax pour enrichir le dynamisme de Trombinoscoop
.....
..c ~ Point final de Trombisnoscoop
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Trombinoscoop est un site web dynamique : le contenu de la plupart des pages est
construit par les utilisateurs du site. Messages publiés, amis ajoutés, profils modifiés,
les pages se construisent à mesure que le site se trouve exploité par les internautes.
Nous ne sommes cependant pas encore parvenus à un niveau de dynamisme équiva-
lant à celui des applications dites « lourdes » (par opposition, sans surprise, à celles
dites« légères»). E n effet, d'une requête HTTP à l'autre, le contenu des pages reste
totalement inchangé tant que l'utilisateur ne soumet pas de formulaire ou ne clique
sur un lien hypertexte.
Prenons l'exemple de la validation d'un formulaire. D ans Trombinoscoop, la valida-
tion des champs se fait côté serveur, une fois le formulaire complètement rempli et
soumis. Or, il serait intéressant de pouvoir avertir l'utilisateur beaucoup plus tôt qu'il
a introduit une donnée erronée, par exemple lorsqu'il a fini cl'encoder un champ et
qu'il se prépare à encoder le suivant.
....
.... ...
Comportement
La plupart du temps, la sollicitation du serveur se conclut par la mise à disposition d'une nouvelle page
HTML qui vient se substituer à celle d'où provient cette sollicitation. Or, souvent, ce n'est pas toute la
page qu'il faudrait remplacer par la nouvelle, mais juste une partie devant simplement être mise à jour
suite aux opérations effectuées par le serveur. On comprend que l'information circulant entre le serveur
et le client peut s'en trouver considérablement allégée.
Plus récemment, et de manière à rendre en effet l'interaction client/serveur plus efficace, la technologie
Ajax (Asynchronous JavaScript and XML, que l'on doit à Google) permet au client de solliciter le serveur
sans quitter la page active. Le résultat du serveur viendra juste s'insérer dans cette dernière sans qu'il
faille entièrement la remplacer par une nouvelle version. C'est du JavaScript s'exécutant côté client; il se
charge de réaliser la connexion avec le serveur pour récupérer des informations et les insérer dans la
page client courante. On parle d'interaction asynchrone car, lorsque le client envoie la requête, il
n'est pas contraint d'attendre la réponse du serveur pour poursuivre sa tâche. C'est seulement quand le
serveur aura terminé l'exécution de sa requête et qu'il renverra le résultat au client, que ce dernier s'en
trouvera informé et agira en conséquence, par exemple en affichant ce résultat sur sa page.
CULTURE
Une des premières grandes exploitations d'Ajax fut « Google Suggest », la complétion automatique des
mots-clés que les internautes commencent à écrire dans le moteur de recherche. Par la suite, Google
Maps et Google Earth en firent un très large usage.
Figure 13-2
Page de création de compte
Nom:
Prenom:
Date de naissance::
1
Courriel:
Teirnoble:
Mot de pas~:
farulœ: ._f=
_____.G...~ I
81.reau:
Vl
Q)
,_
0
Colrpus: [--
B
>- fonction: F GJ
w
N +;m;11u1;.1rnw
.--1
0
N
@
~
Pour valider «en direct» le champ Courriel, dès que l'utilisateur l'a encodé, nous
.c devons ajouter les parties suivantes :
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
• dans la page H TML, du code JavaScript qui s'active dès que l'utilisateur a ter-
miné d'encoder le champ courriel. Il interroge le serveur pour vérifier la validité de
ce qui a été encodé et, le cas échéant, afficher un message d'erreur au niveau du
champ. Nous allons écrire ces lignes JavaScript en nous servant du framework
jQyery vu au chapitre 4.
• au niveau Python, une nouvelle URL et une nouvelle vue afin de traiter la requête
envoyée par le JavaScript. Le rôle de la vue est de vérifier que la donnée envoyée
par le JavaScript est valide et de renvoyer si nécessaire une erreur.
urlpatterns = patterns('' ,
( ' A$', welcome), #au l i eu de login
('A 1ogi n$' , 1ogi n) ,
('Awelcome$', welcome),
('Aregister$', register),
('AaddFriend$', addFriend),
('AshowProfile$', showProfile),
('AmodifyProfile$', modifyProfile),
('Aajax/checkEmailField$', ajax_check_email _field),
('Aadmin/', include(admin.site.urls))
)
Afin d'indiquer clairement qu'il s'agit d'une requête Ajax, on préfixe l'URL avec ajax/.
def ajax_check_email_field(request):
HTML_to_return = ' ' «»
Vl
Q)
return HttpResponse(HTML_to_return)
Cette vue vérifie qu'une adresse de courriel passée en paramètre est valide. Deux
valeurs de retour sont possibles :
• «rien» (un string vide) dans le cas où il n'y a pas d'erreur à signaler;
• une liste HTML d'erreurs, chaque élément de la liste étant un message.
On commence par initialiser la valeur de retour avec le string vide indiquant qu'il
n'y aucune erreur o.
Ensuite, on utilise la classe Field e
de la bibliothèque forms
de Dj ango, car elle implémente déjà la validation d'un courriel (il vous faut pour cela
importer deux nouvelles bibliothèques : from django import forms et from
django.core import exceptions). Dans une instruction try ( .. . ) except, on
appelle la méthode c 1ean de cette classe en lui passant en paramètre la valeur à
valider e.Si la validation ne passe pas, c 1ean lève une exception Q . O n construit
notre liste HTML en parcourant tous les messages d'erreur Q . Enfin, on retourne le
tout au navigateur.
La gestion d'exceptions est un mécanisme de programmation classique pour gérer les problèmes. Nous ne
le détaillerons pas ici, mais vous le trouverez expliqué dans de nombreux manuels de programmation.
Nous pouvons très bien essayer cette URL de manière tout à fait indépendante en l'intro-
duisant dans la barre d'adresse du navigateur. Voilà ce que cela donne si on passe en para-
mètre une adresse de courriel erronée (la liste contient un seul message d'erreur):
Figure 13-3
Essai de notre nouvelle URL 127.0.0.1;8000/ajax/died<E
Vl
Q)
,_
0
>-
w
N
..-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
{% block content %}
Ce code spécifie simplement que lorsque l'événement focusout survient sur l'élé-
ment input d 'id id_courriel , il faut exécuter la fonction checkEmailField Q.
EN PRATIQUE Des id différents pour les champs de courriels des étudiants et des employés
Dans le formulaire permettant de créer à la fois des comptes étudiants et des comptes employés, remar-
quez qu'il y a deux id différents pour le champ de courriel. Pour connaître les id créés par Django, il suf-
fit de regarder les codes sources de la page web sur votre navigateur.
0L.. Il existe un événement jQyery signalant quand le document est pleinement chargé ;
>-
U.J
il s'agit de l'événement ready de l'objet document . Nous allons donc plutôt écrire ce
N qui suit.
.--!
0
N
@
......
..c.
en
ï::::
>-
a.
0
u
Des sites web encore plus dynamiques avec Ajax
CHAPITRE 13
EXEMPLE 13.4 Trombinoscoop. Interception de 1' événement focusout dans le document entièrement
chargé
<Scri pt type="text/javascript">
$(document) . ready(function() f)
{
$("i nput #id_courriel") . focusou t (checkEmailFi eld) ;
}) ;
f unction checkEmailField()
{
alert( ' Courri el introdui t . On va mai ntenant le valider . ');
}
</scri pt>
Figure 13-4
Capture de l'événement Trombinoscoop - Crl!ation d L
~~=--~--::::::::::::::::::::::::::~~~~,1
focusout ~ c Q 127.0.0. l :BOOO/register
trombinoscoop
Création d'un compte
Vl
Q)
Nom:
,_
0
>-
w
N
.--1 Da Courriel inb'odl.lt. On va maantenant le valider •
0
N
OK
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
function checkEmailField()
{
$fieldValue = $("input#id_courriel ") .val (); O
$ .ajax ({ f)
url : ' /ajax/checkEmailFi eld', Q
data: ({value : $fi eldVal ue}) , 0
type: ' GET', 5
success: function($data, $textStatus, $XMLHttpRequest) { 0
if ($data != '')
{
alert($data) ;
}
}
}
)
}
0L.. Si des erreurs se présentent, on affiche une boîte de message reprenant ces erreurs.
>-
UJ
On s'occupera de les insérer dans la page HTML par la suite. Testons le résultat.
N
.-f Comme nous pouvons le constater, si l'adresse est erronée, une boîte de dialogue
0
N apparaît affichant le code HTML de la liste contenant toutes les erreurs.
@
......
..c
en
ï::::
>-
a.
0
u
Des sites web encore plus dynamiques avec Ajax
CHAPITRE 13
Figure 13-5
Affichage de la réponse Trombinoscoop -Cro!ation d"c
trombinoscoop
Création d'un compte
Nom:
Page sur 127.0 .0. 1:8000 says:- - -- - -- :- X -
<U dass •"error1ist"><i>Enter a vaid e~ff address. </1i></ul>
Date de
OK
Courriel: pa
_s_bo_n_ _ _ _ _ _ _ __..
i..:..1
function checkEmailField()
{
$fieldValue = $("input#id_courriel") . val();
$.ajax({
url: '/ajax/checkEmailField',
data: ({value : $fieldValue}) ,
type: ' GET' ,
success : function($data, $textStatus, $XMLHttpRequest) {
if ($data != ")
{
$("input#id_courriel ") . parent(). prev(' . errorl ist'). remove();
$("input#id_courriel ") . pa rent() .before($data); O
}
}
}
vi )
Q)
}
,_
0
>-
w
N
Nous avons ajouté deux lignes : la première pour supprimer une éventuelle liste
.--1
0 d'erreurs qui serait déjà présente, la deuxième pour insérer la nouvelle liste d'erreurs
N
@
fraîchement reçue.
~
.c
Cl'I
·c
>-
o..
0
u
Apprendre la programmation web avec Python et Django
Nous le voyons bien, la liste d'erreurs se trouve juste avant le paragraphe qui contient
le champ, au même niveau que le paragraphe. Ainsi, pour insérer la liste, on part de
l'élément input, on remonte au parent et on l'insère juste avant. C'est exactement ce
qu'exprime la ligne 0 du code Ajax.
Pour réaliser la suppression, on part de l'élément input, on remonte au parent, on
prend l'élément qui précède et on le supprime.
Et voilà! Notre validation Ajax est terminée. Voici le résultat:
Figure 13-6
Le formulaire est Trombinoscoop - Crt!ation dL
trombinoscoop
Création d'un compte
Nom:
Vl
Pr~m: ~C ________=i
~
Q)
Date de naissance:
,_
0
>-
w Matrirul~:
Tront>inoscoop - Accueil
-·
Mes amis
Xa\/Îer Devos dit :
Cesite~st ..,.llirœntghë 1 :-p
</form>
<Ul>
{% for ami in logged_user . amis . all %}
<li><a href="showProfile?userToShow={{ ami . id}}">{{ ami . prenom}}
.,. {{ami . nom }}</a></li>
{% endfor %}
</ul>
</section>
urlpatterns = patterns('',
# Autres URL
( ' Aajax/checkEmai lField$ ', ajax_check_email _f i eld) ,
( ' Aajax/addFriend$', ajax_add_friend),
)
def ajax_add_friend(request):
HTML_to_return = ' ' (i)
logged_user = get_logged_user_from_request(request)
if not logged_user is None: O
if 'email' in request .GET:
new_friend_email = request .GET['email'] f)
i f len(Personne .objects .filter(courriel =new_friend_email)) == 1: Q
new_friend = Personne.objects .get(courriel=new_friend_email)
logged_user.amis.add(new_friend) O
logged_user .save()
$ . ajax({ e
url : '/ajax/addFriend', 0
data : ({email : $fieldValue}) , 0
type : 'GET',
success: function($data, $textStatus, $XMLHttpRequest) { G
alert($data);
}
}
);
return false;
}
</script>
Ce code n'est pas si éloigné de celui de l'exercice précédent. On commence par inter-
cepter les soumissions du formulaire d'ajout d'amis. Chaque fois que le formulaire est
soumis, on appelle la fonction addFri end Q. Dans cette fonction, on récupère
d'abord la valeur du champ contenant l'adresse courriel du nouvel ami f). Ensuite,
on envoie une requête Ajax E) qui appelle l'URL / ajax/addFri end 0 en passant en
paramètre le courriel de l'ami à ajouter Q. Si la requête Ajax se passe au mieux, on
affiche le HTML produit par le serveur (j). En voici le résultat :
t
Trombinoscoop - A«uell
C -
C',;) 127.0.0.1:8000/welcome
Xavier Devos
Eb..ldlant en lèfe Maste" en H1stOl'e
~~
'- IC 1 X
Vl
Q)
,_
0
>-
w
N
.--1 Figure 13- 8 HTML renvoyé par le serveur lors de l'ajout d'un ami
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Des sites web encore plus dynamiques avec Ajax
CHAPITRE 13
function addFriend()
{
$fie ldVa1ue = $ ("#newFri endlnput") . val();
$. ajax({
url : '/ajax/addFriend',
data : ({email : $fieldValue}) ,
type : ' GET' ,
success : function($data, $textStatus, $XMLHttpRequest) {
if ($data ! = '')
{
$('#friendlist ul').prepend($data); 4»
}
}
}
);
return false; f)
}
0L..
>-
UJ
N
.-f
0
N
@
......
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Trombiioscoop - Aa:ueil
+- C © 127.0.0.1:8000/welcome
~~
t Xavier Devos
Étudiant en tere Master en H1stOl'e
Conclusions
Nous le savons, la réalisation finale de Trombisnoscoop n'est finalement pas une si
mince affaire. Elle vous est peut-être apparue, par moments, comme un véritable
parcours du combattant. Nous nous voulions exhaustifs au possible; au-delà de
Django, nous avions l'ambition de vous familiariser à toutes les facettes et tous les
métiers de la programmation web. Si vous avez réalisé et compris ce projet web
jusqu'au bout, vous pouvez fièrement annoncer à tout futur employeur que vous maî-
trisez déjà certaines ficelles de la programmation web, et pas seulement en Django !
À la lecture de ce livre, vous avez affronté et résolu de nombreux problèmes qui vous
seraient apparus tout autant avec d'autres solutions technologiques, issues par
exemple du monde Java ou .Net.
Vl
Q)
Au fil des pages et de la mise en forme de notre Trombisnoscoop, vous avez peut-être
,_
0
>- dû vous procurer d'autres sources d'information pour la programmation Python,
w
N
HTMLS, CSS, JavaScript, Ajax, le modèle relationnel, etc. Notre choix de l'exhaus-
.--1
0 tivité, au détriment parfois de la profondeur de vue, vous aura permis de prendre le
N
@
recul nécessaire, de remettre chaque outil à sa place, de comprendre le pourquoi de
~ cette profusion technologique plutôt confondante qui caractérise le monde de la pro-
.c
Cl'I
·c grammation web. Comme nombre de vos collègues, vous aurez fai t vôtre cette multi-
>-
0..
0
u
Des sites web encore plus dynamiques avec Ajax
CHAPITRE 13
tude de sigles qui, de HTM L, CSS à Ajax, sont autant d'atouts dans votre main. Et
si un soir de vague à l'âme, l'envie vous vient de jeter ce livre et tous ses codes Python
et HTML par la fenêtre, rappelez-vous la belle histoire de Marc Van Saltberg, cet
étudiant bruxellois. Elle devrait vous remonter le moral, vous convaincre d'aller de
l'avant et de tourner la page.
Vl
Q)
0L..
>-
U.J
N
...-!
0
N
@
.....
..c
en
ï::::
>-
a.
0
u
1
1
1
1
1
u)
~
0
!....
>-
LU
N
.-4
0
N
@
......
.s:::
01
·;:
>-
o..
0
u
A
Installation de l'environnement
de développement
Cette annexe décrit étape par étape l'installation des dijférents éléments logiciels nécessaires à la
réalisation du projet Trombinoscoop.
Vl
Q)
0L..
>-
UJ
N
..-!
SOMMAIRE
0
N ~ Annexe décrivant l'installation des différents outils nécessaires au développement web sous Django : Python, Java,
@ Django, Eclipse et plug-ins permettant l'exécution de code Python dans l'environnement Eclipse.
.....
..c ~ Cette installation est décrite pour les trois systèmes d'exploitation les plus répandus: Windows, Mac OS et Linux.
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Python
Le premier outil à installer, et dont on ne pourra pas se passer, est le langage de pro-
grammation Python qui nous permettra de compiler et d'exécuter des programmes
écrits dans ce langage.
Python est accompagné d'une importante bibliothèque standard offrant de nombreux
modules pré-écrits (types de données complexes, cryptographie, traitement d'images,
traitement audio, envoi de courriels, etc.). C'est par l'instruction import qu'on appelle
ces différents utilitaires dans les codes qui en font usage.
Il existe plusieurs implémentations du langage Python et de sa bibliothèque standard.
Nous utiliserons l'implémentation « traditionnelle» de référence, proposée sur le site
web python.org et disponible pour de nombreuses plates-formes (Windows, Linux, etc.).
Python, comme tout langage de programmation qui se respecte, est en constante
évolution ; il en existe plusieurs versions. La dernière version majeure est la 3 et mérite
Vl qu'on s'y attarde un peu. Elle a eu notamment pour objectif de simplifier le langage en
Q)
nière version de Python, qui se fera bien un jour, ne devrait pas modifier pour l'essentiel
notre enseignement et le projet que nous vous proposons.
Django
Une fois Python installé, il faut l'enrichir avec le framework Django, qui n'est pas
prévu de base dans la bibliothèque standard Python. Ce framework se télécharge sur
le site officiel de Django.
Un des avantages de Django est l'intégration d'un serveur web léger. On n'est donc pas
obligé d'installer un serveur web tiers, tel Apache. Bien entendu, si le serveur web léger
inclus dans Django suffit amplement pour tester son site durant la phase de développe-
ment, il n'en sera pas de même lorsqu'on ouvrira son site au public. Un serveur web
tiers plus robuste sera nécessaire, car il permettra de mieux supporter un nombre élevé
de visites sur le site et permettra une configuration plus fine des utilitaires web.
Eclipse
Python et Django suffiraient à débuter le développement de notre premier site web.
À l'aide d'un simple éditeur de texte et d'une interface en ligne de commande, nous
pourrions écrire notre premier code et le lancer. Ce serait néanmoins laborieux et peu
convivial. C'est pourquoi nous allons installer un environnement de développement
intégré ou ID E (Integrated Development Environment) .
DÉFINITION IDE
Un environnement de développement intégré est un ensemble d'outils facilitant et rendant plus convivial
le développement d'applications.
Généralement, les IDE offrent au moins les utilitaires suivants, plutôt précieux:
• un éditeur de texte capable de colorer le code, de détecter les erreurs de syntaxe en
ligne ou d'aider à la saisie de code en affichant toutes les constructions possibles ;
• une interface graphique conviviale pour simplifier la compilation d'un programme
ou le lancement de l'application;
Vl
Q)
• un débogueur graphique permettant d'exécuter pas à pas un programme et d' obser-
0L..
>-
ver son état à tout instant (valeurs des variables, position dans le code, etc.).
U.J
N Notre choix d'environnement de développement intégré s'est porté sur Eclipse car il
T"'f
0
N
s'agit d'un environnement très populaire et complet, capable de gérer plusieurs lan-
@ gages de programmation, dont Python et Django.
.....
..c
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Eclipse est un IDE écrit en Java. C'est aussi à ce jour l'environnement de développe-
ment Java le plus utilisé, sachant que Java est actuellement le langage de programma-
tion le plus répandu et le plus enseigné. Le moteur d'exécution Java, qui permet de
lancer des programmes écrits dans ce langage, devra donc faire partie de la panoplie
d'outils à installer, sans quoi Eclipse ne pourra pas être lancé.
L'installation de base d'Eclipse ne contient pas les modules permettant de gérer le lan-
gage Python et le framework Django. Ces modules, regroupés dans le plug-in nommé
PyD ev, doivent être ajoutés manuellement par la suite, ce que nous ferons également.
En résumé
La mise en place de notre environnement de développement passera par l'installation
successive de ces cinq composants :
• le langage Python, dans sa version 2.7;
• le framework Django ;
• le moteur d'exécution Java (Java Runtime Environment) ;
• l'ID E Eclipse;
• le plug-in Eclipse PyDev.
Les sections suivantes sont consacrées à l'installation de ces éléments sous différents
systèmes d'exploitation. Vous pouvez bien entendu ne lire que les sections qui corres-
pondent à votre environnement.
Figure A-1
Windows 7
professionnel 32 bits
Vl
Q)
,_
0
>-
w
N
..-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Les différentes étapes ont été réalisées et testées sous Windows 7 Professionnel
32 bits, sans service pack installé, Mac OS X Lion et Ubuntu 12.04 dans sa version
32 bits. Elles devraient rester pour 1'essentiel identiques pour les autres versions des
systèmes d'exploitation.
Figure A-2
Mac OS X Lion
Figure A -3
Ubuntu 12.04 32 bits
Vl
Q)
,_
0
>-
w
N
..-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Installation de Python
Commençons par une bonne nouvelle : sous Ubuntu, Python est déjà pré-installé.
Pour Windows et Mac OS X, la première étape consiste à installer l'implémentation
officielle CPython.
~ www.python.org
Pour Windows
Une fois le paquet téléchargé, il suffit de l'exécuter et de suivre les étapes de l'assis-
tant d'installation. À la première étape, l'assistant vous demande si vous désirez ins-
Vl
taller Python pour tous les utilisateurs de l'ordinateur ou juste pour l'utilisateur
Q)
courant; il est recommandé de choisir lnstall for ail users.
0L..
>- L'assistant demande ensuite de choisir un emplacement pour l'installation. Afin de
U.J
N respecter les standards Windows, nous recommandons d'installer Python dans
.-!
0 Program Fi 1 es et non à la racine du disque système, comme proposé par défaut par
N
@ l'installeur.
.....
..c.
en
ï::::
>-
a.
0
u
Installation de l'environnement de développement
ANNEXE A
python
~ :f
windows
Back Next > cancel
e} Python27
python
f(I(
lc:\Program Files\Python27\
windows
<Back Next > cancel 1
Vl
Q)
,_
0
>-
w À la troisième étape, l'installeur demande quels composants de Python installer.
N
...-1
Nous recommandons de tout sélectionner, afin de tout installer.
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
,1·,-·-,9
8 ··~Python
Documentation
.
Please wait while the Instaler installs Python 2.7 .3. This may take
several minutes.
Vl
Q)
,_
0 [ _s_ ifuCj[ Uext >_ j cancel
>-
w
N
.-1
0
N
Python demeurant un langage et un environnement somme toute très léger, l'instal-
@ lation est terminée après quelques minutes. Il ne reste plus qu'à cliquer sur le bouton
~
.c Finish pour fermer l'assistant.
Cl'I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
python
~ :f
d ick the Finish button to exit the InstaUer.
windows
<Back F11ish Cmœl
Pour Mac OS X
Une fois l'image montée, il suffit d'exécuter l'application Pyt hon .mpkg et de suivre les
étapes de l'assistant d'installation. À la fin du processus, on obtient cette fenêtre:
Vl
Q)
python
,_
0
for
>- dick the Rnish button to exit the Installer.
w windows
N
...-1
0 [ < Back 1 Fi nsh l 1 cancel 1
N
@
~
.c
Cl'I Cet installateur met Python dans le dossier Applications de votre Mac.
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Vérification de l'installation
Il reste à valider la bonne installation du langage en lançant par exemple la ligne de
commande graphique Python :
• Démarrer > Tous les programmes > Python > /OLE (Python GUI) sous Windows ;
• Applications > Python 2.7 > /OLE sous Mac OS X.
Ensuite, il suffit de saisir un peu de code, par exemple le sempiternel « hello world »,
bien connu des programmeurs :
EXEMPLE A.1 Petit programme de test
Ce code devrait afficher le texte « Hello World ! » dans la console, comme illustré sur
la figure suivante. Vous pourriez refaire l'exercice avec « Bonjour Monde ! », mais
sachez que cela fait tout de suite beaucoup moins pro.
Figure A-10
7~ Python Shell
Test de l'installation Fife Edit Shen Debug Options Windows H~lp
Python 2 . 7.3 (default, Apr 10 2012, 23 : 31:26) [MSC v.1500 32 bit __J
(Intel)) on win32
Type •copyriQht", "credita• or "licenae ()" for more information .
>>> Ç--n• ( 'Hell.o World! ')
Be llo World!
>>>
Sous Ubuntu, il suffit de lancer un terminal (via le Tableau de bord, on lance l'appli-
cation Terminal) et de taper la commande python . Apparaît alors le numéro de ver-
sion du langage :
Figure A-11
Version de Python
incluse dans Ubuntu
Vl
Q)
,_
0
>-
w
N
...-1
0
N
@
~
.c
OI
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Installation de Django
Django, écrit en Python, n'est pas livré en standard avec ce dernier. Il s'agit d'un fra-
mework tiers à installer manuellement.
Pour Windows et Mac OS X, le framework est disponible en téléchargement sur le
site du projet Django. Il faut se rendre dans la section Download et prendre la der-
nière version officielle. À l'heure où ces lignes sont écrites, il s'agit de la version 1.4.
Le fichier à télécharger se présente sous la forme d'un fichier tar . gz , en d'autres
mots une archive TAR qui a été compressée en format G ZIP.
( • www.djangoproject.com
Pour Windows
Il faut utiliser une application tierce qui va ouvrir, décompresser et extraire les
fichiers d'installation de Django que renferme le fichier ta r . g z . L'application que
nous avons utilisée est 7-Zip, disponible gratuitement. D 'autres décompresseurs et
extracteurs peuvent bien entendu être utilisés. Ouvrez le fichier . gz à l'aide de
l'application 7-Zip. Un seul dossier se présente dans l'explorateur de l'archive: d i st.
.
Figure A-12
~ C:\Users\P1erre\Downloads\Djan90·1.4.tar.9z\
Contenu de l'archive TAR Fichier Edition Affichage Favons Outils Aide
m 1
0 objet(s) sélectionné(s)
Vl
Q)
,_
0
>- Double-cliquez sur le dossier di s t pour en afficher le contenu. Un seul fichier s'y
w
N trouve : Dj ango-1 . 4 . t a r . À nouveau, double-cliquez sur ce fichier TAR pour en affi-
..-1
0 cher le contenu. Dans cette archive, se trouve un seul dossier, nommé Dj ango- 1.4 ;
N
@ cliquez sur le bouton Extraire de 7-Zip. Un emplacement destiné à accueillir le dos-
~
.c sier extrait vous est demandé ; choisissez celui qui vous convient le mieux.
OI
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
L'archive extraite, nous pouvons lancer l'installeur qui s'y trouve. Cet installeur étant
écrit en Python, on ne peut pas le lancer comme un exécutable Windows traditionnel en
double-cliquant dessus. Il va falloir le lancer en ligne de commande en utilisant Python.
Il faut d'abord lancer une ligne de commande Windows, avec les droits d'administrateur.
La lit,rne de commande Windows se trouve dans Menu démarrer> Tous les programmes>
Accessoires>lnvite de commande. Pour la lancer avec les droits d'administrateur, il faut
cliquer droit sur son raccourci et choisir Exécuter en tant qu'administrateur.
Une fois l'invite de commande lancée, il faut se rendre, à l'aide de la commande cd,
dans le dossier d'installation de D jango que l'on vient d'extraire. Par exemple, ayant
extrait ce dossier dans C:\Users\Pierre\Down l oads\, nous avons tapé la ligne de
commande suivante :
1 cd Downloads\Django- 1.4
Nous n'avons pas spécifié le chemin absolu dans la commande, car en ouvrant la con-
sole, celle-ci nous avait déjà positionnés dans le dossier c: \Use rs \Pierre .
Pour lancer l'installation de Django, il faut entrer la commande suivante :
Figure A-13
lancement de l'installation de
Django
Vl
Q)
,_
0
Si aucune erreur ne survient, c'est que l'installation s'est bien déroulée.
>-
w
N
...-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Figure A-14
Installation terminée de Django
Pour Mac OS X
Pour l'archive sous Mac, il faut utiliser la ligne de commande. Ouvrez d'abord un Ter-
minal (dans Applications > Utilitaires). Rendez-vous ensuite dans le dossier où a été
téléchargée l'archive, à l'aide de la commande cd :
EXEMPLE A.3 Positionnement dans le dossier de téléchargement
1 cd Downloads
,_
0
>- sudo /Library/Frameworks/Python.framework/Versions/2 .7/bin/python
w setup.py install
N
...-1
1
0
N Attention, il va falloir entrer le mot de passe administrateur.
@
~
.c
La figure suivante illustre l'utilisation de cette commande.
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure A-16
Installation terminée de Django
Pour Ubuntu
Django est disponible dans la Logithèque d'Ubuntu. Il suffit de chercher le logiciel
pyt hon-d j ango et, celui-ci trouvé, de cliquer sur Installer.
Vl
Q)
,_
0
Plus d'informations
>-
w
N
..-1
0
N Arficher 54 elements techniques
@
~
.c
Cl'I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Vérification de l'installation
Sous Windows et Mac OS X, on peut tester si l'installation s'est exécutée correcte-
ment en lançant une console Python et en tapant le code suivant :
SYNTAXE. Vérification de la bonne installation de Django sous Windows et Mac OS X
Le code doit afficher la version de Django, soit« 1.4 », comme illustré à la figure sui-
vante.
python
>>> import django
>>> print(django.get_version())
1. 3.1
Le code doit afficher la version de Django, soit« 1.3.1 », comme illustré à la figure
suivante.
Vl
Q) Figure A-19 ô ~ - pierre@lpierre-VlrtualBox: -
,_
0 Vérification de la bonne pler re@plerre - VlrtualBox:-S python
>-
w installation de Django Python 2.7.3 (default, Apr 20 2012, 22:44:07)
(GCC 4.6.3] on llnux2
N sous Ubuntu Type "help " , "copyrlght " , "credlts " or "llcense " for More lnfo rMatlon.
..-1
>>> lMport django
0
N > > > prlnt(django.get_ve r slon() )
1. 3.1
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Installation de Java
Si Java n'est pas déjà installé sur votre ordinateur (ce qui est peu probable), vous
devrez y remédier.
• www.java.com
Pour Ubuntu
Rendez-vous à nouveau dans la Logithèque. Il suffit d'y chercher «Java», de sélec-
tionner Open) OK java 7 Runtime et de cliquer sur Installer.
Installer
Vl
Q)
-~!':L~L'"°""""'ntint..!.'
Afficher 2208 éléments techniques
,_
0
>-
w
N
..-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Installation d'Eclipse
Nous allons maintenant installer Eclipse, notre environnement de développement intégré.
Le téléchargement d'Eclipse se fait via le site officiel du projet pour Windows et
Mac OS X. On retrouve sur cette page plusieurs versions de l'outil, chacune ciblant
un langage de programmation ou un usage bien précis. Elles ne sont en fait que la
version de base de l'outil sur laquelle ont été pré- installés les plug-ins ad hoc.
1 ~ http:/lwww.eclipse.org/downloads/
Comme il n'en existe pas pour Python et Django, nous allons simplement télécharger la
version de base,« Eclipse Classic »pour Windows ou Mac (version 3.7.2 au moment où
nous écrivons ces lignes), et nous installerons par la suite les plug-ins qui nous intéressent.
U ne fois téléchargé, Eclipse se présente sous la forme d'une archive (ZIP pour W in-
dows et tar.gz pour Mac), qu'il suffit de décompresser comme nous l'avons fait pour
Django. Elle contient un dossier reprenant tous les fichiers de l'application. Aucun
installateur n'est donc à lancer; il suffit de déplacer le dossier que l'on a décompressé
de l'archive à l'emplacement de son choix. Pour notre part, nous avons choisi de
déplacer le dossier dans C: \Program Fi 1 es sur Windows et Applications pour Mac.
Pour U buntu, nous allons faire usage une fois encore de la Logithèque. Il suffit de
chercher Eclipse, de le sélectionner et de cliquer sur Installer.
'rl.R.
i:J
Extensible Tool Platform and Java IDE
eclipse
*'*** (3)
Installer
,_
0
fl'9 Wireframesketcher Studio (Trial) (2)
>- M WireframeSketcher. woreframino toolforprofe~ooats
w
N ""'1 Stellarium (2581
...-1 . . . Un planétanum interactif
0
N
~_1!d..r,oid User AU5gabe 6/2012 (Deutsch) US$4.20
@
Afficher SS éléments techniques
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure A-22
Création et utilisation Select a workspace
du workspace Eclipse SOK stores your projects on a folder called a worlcspace
C:\Users\Pierre\Projets Cho ose a workspace folder to use for this session.
(Windows)
Workspace: C:\Users\ Piene\ Projets • 1 Browse...
OK J I Cancel
Vl
Q)
,_
0
>-
w
N
..-1
0
N
@
~
.c
Cl"I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Il reste à cliquer sur OK. Eclipse s'ouvre alors et affiche sa page d'accueil.
Welcome to Eclipse
--
- • . -1
Et voilà! Eclipse est installé, Nous n'avons plus à nous occuper que du plug-in PyDev.
Vl
Q) Installation du plug-in Eclipse PyDev
,_
0
>-
w Avant de pouvoir commencer à développer en Python et Django dans Eclipse, il
N
..-1
nous faut installer le plug-in PyDev.
0
N Les plug-ins s'installent via le menu Help > /nstall New Software ... La fenêtre suivante
@ apparaît:
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure A-25
Écran d'installation de plug-ins A~ilablo Softw1"'
t1nd more software by WOfkmg wrtfl the Ayallable Sçftwire S1tn• preferences.
Na me Ve~ion
~•dAll JŒ •selodAll J
De.ails
0 Show onJy the latest versions of available software Ü Hide items that are afready instaHed
~ <ifoup items by cetegory Whal is alre.Jdy in$lallecP.
El Show ottly software ~pplïcable to ta(get environment
~ Contact all update sites. during inst:all to fïnd reqtured software
Tout d'abord, nous devons renseigner le site sur lequel se trouve le plug-in PyDev.
Cliquez sur le bouton Add... et, dans la fenêtre qui apparaît, inscrivez PyDev et
http://pydev . org/updates.
~ pydev.org/updates
Vl
Q)
,_
0 __o_K_ _l I Canet!
>-
w
N
..-1
0
N
Cliquez sur OK. Choisissez ensuite PyDev dans la liste des plug-ins disponibles à ins-
@ taller.
~
.c
OI
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
Na me Version
1> ~ Ill PyDev
t> !:J JJI PyOev Mytyn lntegration (optionaO
Ot'tails
ltJ Show on!y the latest ve:rsions of available: software [i Hide: items that are already instded
f1} Gtoup items by utegory What is ahe4dy installed?
El Show only software appricable to targeten\lironmet1t
['JI Contaa au update sites during install to find required software
On clique sur Next deux fois, on accepte la licence, on clique sur Finish et l'installation
débute.
Figure A-28
~ lnstaDing Software
Installation de PyDev
D lnstalling Software
,_
0
>-
w Au cours de l'installation, E clipse vous demandera de valider un certificat. Il suffit de
N
.-1 s'assurer qu'ils sont tous sélectionnés et de cliquer sur OK.
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure A-29
~ Sel~on Needed
Installation de PyDev
Do you trust these certificates?
1Oetails ]
<1) OK 11 Cancel
Il est possible qu'à ce stade, on vous demande de redémarrer votre ordinateur, pour que
les plug-ins s'installent vraiment. Vous pouvez vous contenter de réexécuter Eclipse.
Il reste maintenant à configurer PyD ev pour lui indiquer où se trouve le compilateur
Python et ses bibliothèques (que nous avons installées au tout début de ce chapitre).
Pour ce faire, il faut aller dans le menu Window > Preference (ou Eclipse > Preference).
D ans l'arborescence de paramètres, rendez-vous à la section PyDev > lnterpreter -
Python .
Cliquez sur le bouton Auto Conjig. Dans la fenêtre qui apparaît, choisissez tous les
éléments du dossier d'installation de Python. Cliquez sur OK pour valider.
Si Auto Config ne marche pas, il suffit alors de faire New et de spécifier comme empla-
Vl
Q) cement l'endroit où se trouve l'exécutable de l'interpréteur Python que l'on désire
,_
0 utiliser. Par exemple, pour Mac OS X, il s'agira de /Li brary/Frameworks/
>-
w Python . framework/Versions/2.7/bin/python .
N
..-1
0 La configuration est maintenant terminée, cliquez sur OK pour fermer la fenêtre de
N
@
préférences.
~
.c
OI
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
~...... D~ L Apply J
® OK 1[ Cancel
J
IMPORTANT: The fold~s f01 your PROJECTS shoutd NOT be added her~ but in your projed configuration.
'"
Vl
Q)
1Select Ail not fn Wortcspace l I Sëe<t Ali ! 1 O.Sel•ct Ali
,_
0
~-O_K_~I [ J
>- ® Cancel
w
N
...-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Figure A-33
Installation du plugin << Web
- -
·-··
·
~
Available Software
Developer Tools » Check the items that yoo wi41 to nstall.
1 1 xt 1
Naine Venion Fl
D ~ Edipse Faceted Project Framewori< 3. 3.2.v20 1201121600-37/ŒiSs 7357...
0 '01 Edlpse Faceœd Project Framewori< JDT &iablement 3. J.O. v20l 10220055S-377Df8s735"...
D~ Edipse Java EE Deve!oper Tools 3.3.2.v20 1111030soo-7bm 1YFSK2. ..
3. 3. 2. v20l l120720'19-7H7B'Z?DlCl.I•..
:
Oetalls
Edpse Web DeveloperTools, lncludrlQ HTM., CSS, XH!Ml, etc.
More...
0 Show only the latest versions of avallable software 0 tilde items that are alreadv lnstalled
~Sf'oup items by caœvorv What is a1~~ m!illl'51?
D Show only software applicable Io target environrnent
0 Q>ntact ail update sites dt.mg install to flid requlred software
CV [iad:
1 tf•Jd > 1 1 Cancel 1
Vl
Après avoir cliqué sur Next, un assistant de création de projet se lance. À la première
Q)
étape, il suffit de donner un nom au projet.
,_
0
>-
w
Cliquez alors sur Finish . Notre projet est créé et apparaît dans l'écran principal
N d'Eclipse.
...-1
0
N
@
~
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Waards:
Ll>"!'• filter text
r.aa Plug-in Project
~ General
(à. cvs
la Java
(à. Plug-in Oevelopment
'2;j. PyOev
GJ PyOev Ojango Project
à PyDev Google App Eng1ne ProJect
fil'< PyDev Project
Figure A-35
Création d'un projet de test
PyDev Project
ûeate • new Pydev Project.
Project contents
17 U•edefault
r ectory C:\Usero\Pierre\ProJet•'îest
Project type
Choose the project type
o Python Jython Iron Python
Grammar Version
2.7
lnterpreter
Odault
Click: here to configure an 1ntemrettt not ftSted.
IO Add projec:t d"ectory to the PVTHONPATH?
Vl
Q) F" Create 'ore' folder and add it tothe PYTHONPATH?
,_
0 \:_,, Oon't configure PYTHON PATH (to be done manually later on)
>-
w
N
...-1
0
N < làck Next > _ _Fi_
n_ish_~J I ~ncel
@
~
.c
Cl'I
·c
>-
0..
0
u
Installation de l'environnement de développement
ANNEXE A
- - ,,,..
Il reste à ajouter à notre projet un fichier py qui va contenir nos sources. Cliquez-
droit sur le projet Test et choisissez New > PyDev Module. Une fenêtre apparaît dans
laquelle on précise un nom pour le projet (Mai n) et un template de base; dans notre
cas, nous allons choisir le template Module: Main, car nous allons écrire notre code au
niveau du point d'entrée du programme.
Figure A-37
o [ ~ l 1'3
Création d'un projet de test ----~ ..a
Package
Nam<! Main
<Empty>
Modul.: Class
Vl Module: Main
Q) Template
Modul.: Unitt<!St
,_
0 Module: Unitt6t w;th setUp and tearOown
>-
w
N
...-1
0
N
@
~
Finish 11 Cancel
.c
Cl'I
·c
>-
0..
0
u
Apprendre la programmation web avec Python et Django
Cliquez sur Finish, le fichier est alors créé. Supprimez-en tout le contenu, en particulier les
commentaires ajoutés par défaut par Eclipse, car pour peu qu'ils contiennent des accents,
Python plantera. Nous verrons comment gérer correctement les accents dans le chapitre 8.
Cela nous permettra de garder le code proposé en standard dans ces fichiers.
Il reste à insérer le code suivant dans le fichier fraîchement créé :
Figure A-38 o [ 13
t1
----~ ..a
Création d'un projet de test
Create a new Pytnon module I!!!!!'.:
Source Folder /Test 1Browse... j
Package
- - - - - - - - - - - - - - - , Browse... j
Na me Main
<Empty>
Module: Class
Module: Main
Template
Module: Unittest
Module: Unittest with se!Up and tearDown
Finish J I Cancel
Et voilà ! Nous avons créé un programme Python en utilisant Eclipse et son plug-in
PyD ev. Nous sommes prêts pour des projets plus complexes ayant recours au fra-
mework Django.
Vl
Q)
,_
0
>-
w
N
...-1
0
Ai-je bien compris ?
N
@
• Pourquoi faut-il installer Java alors que l'on va programmer en Python ?
~
.c • Eclipse est-il obligatoire pour développer un site en Django ?
OI
·c • À quoi sert le plug-in Eclipse « PyDev » ?
>-
0..
0
u
Index
A dimension des éléments 86
Access 131 display 98
Ajax (Asynchronous JavaScript and XML) 270 font-family 79
height 79, 86
B hover 82
base de données 12 inline 88
nettoyer 234 link 82
base de données relationnelle 214 marges par défaut 95
clé primaire 114, 119 margin 86
lien 208 padding 86
relation 1-1116 position 89
relation 1-n 114 positionnement par défaut 88
relation n-n 117 propriété 79
c relative 89
cardinalité d'un lien 122 sélecteur 79
cas d'utilisation 104 sortir un élément du flux 89
CGI (Common Gateway Interface) 126, 131, static 89
133, 145 top 89
cgi-bin 133, 139 visited 82
classe 45 width 86
attribut 45 D
attribut statique 48 DHTML (Dynamic HTML) 96- 97
constructeur 4 7 diagramme de classes 202
clé Django 23, 289
primaire 115, 129 _startswith 212
cookie 233, 238 _str_218
durée de vie 235 _unicode_ 218
CSS (Cascaded Style Sheets) 58, 60 _set 213
Vl
Q) * (sélecteur) 83 action 186, 188
0L.. absolute 90
>- admin.py 215
UJ active 82 ajax/ 272
N
.-f
background-color 79 all 248
0 block 88
N as_p 193
@ border 86 as_table 193
...... border-width 79
..c autodiscover() 215
en
ï::::
>-
a.
0
u
Apprendre la programmation web avec Python et Django
H script 99
héritage 17, 120 section 66
HTML (HyperText Markup Language) 58- 59, src 72
126, 138, 145 strong 73
a 70 style 83- 84
action 76 submit 75- 76
alt 72 text 75
article 66 title 61
aside 68 type 75
attribut 62 ul 71
balise 60 value 76
body 63 width 72
change 96 XHTML60
class 81 xrnlns 63
click 96 HTTP (H yperT ext T ransfer Protocol)
dblclick 96 redirection 186
dl259 requête 75, 187
em 73
encoding 65
Informix 131
figcaption 72
instruction Python
figure 72
_ init_ 45
footer 68
_str_ 47
form 75
append 35
formulaire 75
class 45
hl, h2, h3 67
def...return 43
head 63
del 36
header 68
for. ..in 41
height 72
if... elif..else 39
html 63
if...else 37
id 80
import 288
image 72
indentation 38
img72
insert 35
input 75
len 35
lang 62
print 31, 138
li 71
self 47
link 85
Vl type 31
Q) liste 71
while 40
0L.. method 76
>- instruction SQ!.,
UJ mise en évidence de texte 73
DELETE FROM ...WHERE 132
N mouseover 96
.-f
0
INSERT INTO ... VALUES 132
N
name 76
SELECT. .. FROM ...WHERE 131
@ ol 71
...... UPDATE ... SET. ..WHERE 132
..c onclick 99
en intégrité des données 233
ï::::
p 66
>-
a.
0
u
Apprendre la programmation web avec Python et Django
Vl
Q)
0L..
>-
UJ
N
..-!
0
N
@
......
..c
en
ï::::
>-
a.
0
u