Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

article.md 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. title: Rédaction de votre première appli Django, partie 1 : Initialisation, création des modèles et API de la base de données
  2. slug: redaction-de-votre-premiere-appli-django-partie-1-initialisation-creation-des-modeles-et-api-de-la-base-de-donnees
  3. date: 2006-06-17 17:57:32
  4. type: post
  5. vignette: images/logos/django.png
  6. contextual_title1: Le langage de template Django : Pour les auteurs de templates
  7. contextual_url1: 20060815-le-langage-de-template-django-pour-les-auteurs-de-templates
  8. contextual_title2: Comparaison de TurboGears et Django, deux frameworks web Python
  9. contextual_url2: 20060715-comparaison-de-turbogears-et-django-deux-frameworks-web-python
  10. contextual_title3: Rédaction de votre première appli Django, partie 4 : Conception d'un formulaire et vues génériques
  11. contextual_url3: 20060617-redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques
  12. <p>Apprenons par l'exemple.</p>
  13. <p>À travers ce tutoriel, nous aborderons la création d'une application basique de
  14. sondage.</p>
  15. <p>Cela consistera en deux parties:</p>
  16. <blockquote>
  17. <ul class="simple">
  18. <li>Un site public qui permet aux internautes de voir les sondages et de
  19. voter.</li>
  20. <li>Un site d'administration qui vous permet d'ajouter, modifier et supprimer
  21. un sondage.</li>
  22. </ul>
  23. </blockquote>
  24. <p>Nous considèrerons que vous avez déjà <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-comment-installer-django/">Django d'installé</a>. Vous pouvez tester
  25. si Django est installé en lançant l'interpréteur interactif Python et en tapant
  26. <tt class="docutils literal"><span class="pre">import</span> <span class="pre">django</span></tt>. Si cette commande s'exécute sans erreur, c'est que Django est
  27. bien installé.</p>
  28. <div class="section">
  29. <h1><a id="cr-ation-d-un-projet" name="cr-ation-d-un-projet">Création d'un projet</a></h1>
  30. <p>Si vous utilisez Django pour la première fois, vous devrez faire attention à
  31. quelques options de la configuration initiale. En effet, vous aurez besoin
  32. d'auto-générer du code qui met en place un <em>projet</em> Django -- une configuration
  33. propre à chaque instance de Django, incluant la configuration de la base de
  34. données, les options spécifiques à Django et la configuration spécifique aux
  35. applications.</p>
  36. <p>En ligne de commande, faites <tt class="docutils literal"><span class="pre">cd</span></tt> d'un répertoire où vous aimeriez conserver
  37. votre code, puis lancez la commande <tt class="docutils literal"><span class="pre">django-admin.py</span> <span class="pre">startproject</span> <span class="pre">monsite</span></tt>.
  38. Ceci va créer un répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt> dans le répertoire courant.</p>
  39. <p>(<tt class="docutils literal"><span class="pre">django-admin.py</span></tt> devrait être dans votre path système si vous avez installé
  40. Django via <tt class="docutils literal"><span class="pre">python</span> <span class="pre">setup.py</span></tt>. S'il n'est pas dans votre path, vous pouvez le
  41. trouver dans <tt class="docutils literal"><span class="pre">site-packages/django/bin</span></tt>, où <tt class="docutils literal"><span class="pre">site-packages</span></tt> est un
  42. sous-répertoire de votre installation Python. Faites un lien symbolique de
  43. <tt class="docutils literal"><span class="pre">django-admin.py</span></tt> quelque part dans votre path, typiquement
  44. <tt class="docutils literal"><span class="pre">/usr/local/bin</span></tt>.)</p>
  45. <div class="admonition-o-devrait-on-mettre-le-code admonition">
  46. <p class="first admonition-title">Où devrait-on mettre le code ?</p>
  47. <p>Si vous avez connu le PHP, vous êtes probablement habitué à mettre le code
  48. dans le répertoire de documents du server Web (dans un endroit comme
  49. <tt class="docutils literal"><span class="pre">/var/www</span></tt>). Avec Django, ne faites pas ça. Ce n'est pas une bonne idée de
  50. mettre du code python dans votre répertoire de documents du serveur Web
  51. parce que vous prennez le risquez que l'on puisse voir votre code depuis le
  52. Web. Ce n'est pas bon d'un point de vue de la sécurité.</p>
  53. <p class="last">Mettez votre code dans un répertoire <strong>à l'extérieur</strong> du répertoire de
  54. documents, par exemple <tt class="docutils literal"><span class="pre">/home/moncode</span></tt>.</p>
  55. </div>
  56. <p>Jetons un œil à ce que <tt class="docutils literal"><span class="pre">startproject</span></tt> a créé:</p>
  57. <pre class="literal-block">
  58. monsite/
  59. __init__.py
  60. manage.py
  61. settings.py
  62. urls.py
  63. </pre>
  64. <p>Ces fichiers sont:</p>
  65. <blockquote>
  66. <ul class="simple">
  67. <li><tt class="docutils literal"><span class="pre">__init__.py</span></tt>: Un fichier vide que dit à Python que ce répertoire
  68. doit être considéré comme un paquetage Python. (En savoir <a class="reference" href="http://docs.python.org/tut/node8.html#packages">plus sur les
  69. paquetages</a> dans la documentation officielle de Python si vous êtes
  70. débutant en Python.)</li>
  71. <li><tt class="docutils literal"><span class="pre">manage.py</span></tt>: Un outil en ligne de commande que vous permet d'intéragir
  72. avec ce projet Django de différentes manières.</li>
  73. <li><tt class="docutils literal"><span class="pre">settings.py</span></tt>: Fichier de configuration de ce projet Django.</li>
  74. <li><tt class="docutils literal"><span class="pre">urls.py</span></tt>: Les déclarations d'URLs pour ce projet Django ; il s'agit
  75. d'une « table des matières » de votre site géré par Django.</li>
  76. </ul>
  77. </blockquote>
  78. <div class="section">
  79. <h2><a id="le-serveur-de-d-veloppement" name="le-serveur-de-d-veloppement">Le serveur de développement</a></h2>
  80. <p>Vérifions que tout ceci fonctionne. Placez-vous dans le répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt>,
  81. si vous ne l'avez pas déjà fait, lancez la commande <tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span>
  82. <span class="pre">runserver</span></tt>. Vous verrez la trace d'exécution suivante dans votre terminal:</p>
  83. <pre class="literal-block">
  84. Validating models...
  85. 0 errors found.
  86. Django version 0.95, using settings 'monsite.settings'
  87. Development server is running at http://127.0.0.1:8000/
  88. Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
  89. </pre>
  90. <p>Vous avez démarré le serveur de développement de Django, un serveur web léger
  91. écrit entièrement en Python. Nous l'avons intégré à Django pour que vous
  92. puissiez développer des choses rapidement, sans avoir à vous occuper de la
  93. configuration d'un serveur de production -- tel Apache -- jusqu'à ce que
  94. vous soyez prêt à passer en production.</p>
  95. <p>À présent, c'est le bon moment pour noter : N'utilisez PAS ce serveur
  96. pour quoi que ce soit ressemblant à un environnement de production. C'est
  97. seulement destiné à une utilisation pendant le développement
  98. (Nous concevons des frameworks Web, pas des serveurs Web).</p>
  99. <p>Maintenant que le serveur tourne, visitez la page
  100. <a class="reference" href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a> avec votre navigateur Web. Vous verrez une page
  101. « Welcome to Django », dans un agréable bleu clair pastel. Ça marche !</p>
  102. <div class="admonition-changement-du-port admonition">
  103. <p class="first admonition-title">Changement du port</p>
  104. <p>Par défaut, la commande <tt class="docutils literal"><span class="pre">runserver</span></tt> démarre le serveur de
  105. développement sur le port 8000. Si vous voulez changer le port du
  106. serveur, passez-le en tant qu'argument à la ligne de commande. Par
  107. exemple, cette commande démarre le serveur sur le port 8080:</p>
  108. <pre class="literal-block">
  109. python manage.py runserver 8080
  110. </pre>
  111. <p class="last">Une documentation complète sur le serveur de développement se
  112. trouve dans la <a class="reference" href="http://www.djangoproject.com/documentation/django_admin/">documentation de django-admin</a>.</p>
  113. </div>
  114. </div>
  115. <div class="section">
  116. <h2><a id="configuration-de-la-base-de-donn-es" name="configuration-de-la-base-de-donn-es">Configuration de la base de données</a></h2>
  117. <p>Maintenant, éditez le fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>. C'est un module Python
  118. normal avec des variables de module représentant les options de
  119. configuration de Django. Modifiez ces options pour qu'elles correspondent à vos
  120. paramètres de connexion à votre base de données:</p>
  121. <blockquote>
  122. <ul class="simple">
  123. <li><tt class="docutils literal"><span class="pre">DATABASE_ENGINE</span></tt> -- Au choix parmi 'postgresql', 'mysql' ou 'sqlite3'.
  124. D'autres viendront bientôt.</li>
  125. <li><tt class="docutils literal"><span class="pre">DATABASE_NAME</span></tt> -- Le nom de votre base de données, ou le
  126. chemin complet (absolu) du fichier de base de données si vous
  127. utilisez SQLite.</li>
  128. <li><tt class="docutils literal"><span class="pre">DATABASE_USER</span></tt> -- Le nom d'utilisateur de la base de données
  129. (non utilisé pour SQLite).</li>
  130. <li><tt class="docutils literal"><span class="pre">DATABASE_PASSWORD</span></tt> -- Le mot de passe de la base de données
  131. (non utilisé pour SQLite).</li>
  132. <li><tt class="docutils literal"><span class="pre">DATABASE_HOST</span></tt> -- Le nom d'hôte sur lequel est votre base de
  133. données. Laissez une chaîne vide si votre serveur de base de
  134. données est sur la même machine physique (non utilisé pour SQLite).</li>
  135. </ul>
  136. </blockquote>
  137. <div class="admonition-note admonition">
  138. <p class="first admonition-title">Note</p>
  139. <p class="last">Si vous utilisez PostgreSQL ou MySQL, assurez-vous d'avoir créé
  140. une base de données à cette étape. Faites cela avec « <tt class="docutils literal"><span class="pre">CREATE</span>
  141. <span class="pre">DATABASE</span> <span class="pre">base_de_donnees;</span></tt> » à l'invite du client interactif de
  142. votre base de données.</p>
  143. </div>
  144. <p>Pendant que vous éditez <tt class="docutils literal"><span class="pre">settings.py</span></tt>, notez la présence de l'option
  145. <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> vers la fin du fichier. Cette variable contient le
  146. nom de toutes les applications Django qui sont activées dans cette
  147. instance de Django. Les applis peuvent être utilisées dans de
  148. multiples projets, et vous pouvez les empaqueter et les distribuer
  149. pour que d'autres les utilisent dans leurs projets.</p>
  150. <p>Par défaut, <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> contient les applis suivantes, toutes
  151. sont fournies avec Django:</p>
  152. <blockquote>
  153. <ul class="simple">
  154. <li><tt class="docutils literal"><span class="pre">django.contrib.auth</span></tt> -- Un système d'authentification.</li>
  155. <li><tt class="docutils literal"><span class="pre">django.contrib.contenttypes</span></tt> -- Un framework pour les types
  156. de contenu.</li>
  157. <li><tt class="docutils literal"><span class="pre">django.contrib.sessions</span></tt> -- Un framework gérant les sessions.</li>
  158. <li><tt class="docutils literal"><span class="pre">django.contrib.sites</span></tt> -- Un framework pour gérer plusieurs sites
  159. avec une seule installation de Django.</li>
  160. </ul>
  161. </blockquote>
  162. <p>Ces applications sont incluses par défaut car elles conviennent pour
  163. la plupart des cas.</p>
  164. <p>Chacune de ces applications entraîne l'utilisation d'au moins une
  165. table de base de données, par conséquent, nous avons besoin de créer
  166. ces tables dans la base de données avant que nous puissions les
  167. utiliser. Pour ce faire, lancez la commande suivante:</p>
  168. <pre class="literal-block">
  169. python manage.py syncdb
  170. </pre>
  171. <p>La commande <tt class="docutils literal"><span class="pre">syncdb</span></tt> regarde l'option <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> et crée
  172. toutes les tables de base de données nécessaires selon la
  173. configuration de la base de données dans votre fichier
  174. <tt class="docutils literal"><span class="pre">settings.py</span></tt>. Vous verrez un message pour chaque table que ça crée,
  175. et vous aurez une invite vous demandant si vous aimeriez créer un
  176. compte superutilisateur pour le système d'authentification. Continuez
  177. et faites-le.</p>
  178. <p>Si cela vous intéresse, exécutez le client intéractif de votre base de
  179. données et tapez <tt class="docutils literal"><span class="pre">\dt</span></tt> (PostgreSQL), <tt class="docutils literal"><span class="pre">SHOW</span> <span class="pre">TABLES;</span></tt> (MySQL), ou
  180. <tt class="docutils literal"><span class="pre">.schema</span></tt> (SQLite) pour afficher les tables que Django a créées.</p>
  181. <div class="admonition-pour-les-minimalistes admonition">
  182. <p class="first admonition-title">Pour les minimalistes</p>
  183. <p class="last">Comme nous avons dit plus haut, les applications par défaut sont
  184. incluses pour les cas courants, mais tout le monde n'en a pas
  185. forcément besoin. Si vous n'avez pas besoin d'une ou plusieurs
  186. d'entre elles (voire toutes), libre à vous de commenter ou supprimer
  187. la ou les lignes appropriées dans <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> avant de
  188. lancer <tt class="docutils literal"><span class="pre">syncdb</span></tt>. La commande <tt class="docutils literal"><span class="pre">syncdb</span></tt> créera les tables uniquement pour
  189. les applis qui sont dans <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt>.</p>
  190. </div>
  191. </div>
  192. </div>
  193. <div class="section">
  194. <h1><a id="cr-ation-de-mod-les" name="cr-ation-de-mod-les">Création de modèles</a></h1>
  195. <p>Maintenant que notre environnement -- un &quot;projet&quot; -- est initialisé,
  196. vous pouvez commencer à travailler.</p>
  197. <p>Chaque application que vous écrivez dans Django constitue un paquetage
  198. Python, quelque part dans votre <a class="reference" href="http://docs.python.org/tut/node8.html#SECTION008110000000000000000">Python path</a>, qui suit une certaine
  199. convention. Django est fourni avec un utilitaire que génère
  200. automatiquement la structure basique du répertoire d'une appli, vous
  201. pouvez donc vous focaliser sur la rédaction du code plutôt que sur la
  202. création des répertoires.</p>
  203. <div class="admonition-projets-contre-applis admonition">
  204. <p class="first admonition-title">Projets contre applis</p>
  205. <p class="last">Quelle est la différence entre un projet et une appli ? Une appli
  206. est une application web que fait quelque chose -- par exemple, un
  207. système de weblog, une base d'enregistrements publics ou une simple
  208. appli de sondage. Un projet est un ensemble de paramètres et
  209. d'applications pour un site Web particulier. Un projet peut
  210. contenir plusieurs applis. Une appli peut être dans plusieurs projets.</p>
  211. </div>
  212. <p>Dans ce tutoriel, nous allons créer notre appli de sondage dans le
  213. répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt>, pour plus de simplicité. En conséquence,
  214. l'appli sera couplée au projet -- c'est-à-dire que le code Python dans
  215. l'appli de sondage réfèrera à <tt class="docutils literal"><span class="pre">monsite.polls</span></tt>.
  216. Plus tard dans le tutoriel, nous discuterons du découplage de vos
  217. applications pour les distribuer indépendamment.</p>
  218. <p>Pour créer votre appli, assurez-vous que vous êtes dans le répertoire
  219. <tt class="docutils literal"><span class="pre">monsite</span></tt> et tapez la commande:</p>
  220. <pre class="literal-block">
  221. python manage.py startapp polls
  222. </pre>
  223. <p>Cela créera un répertoire <tt class="docutils literal"><span class="pre">polls</span></tt>, qui est décrit comme suit:</p>
  224. <pre class="literal-block">
  225. polls/
  226. __init__.py
  227. models.py
  228. views.py
  229. </pre>
  230. <p>Cette structure du répertoire va accueillir l'application de sondage.</p>
  231. <p>La première étape dans la rédaction d'une appli Web utilisant la base
  232. de données est de définir vos modèles -- essentiellement, la
  233. description de votre base de données, avec des méta-données additionnelles.</p>
  234. <div class="admonition-philosophie admonition">
  235. <p class="first admonition-title">Philosophie</p>
  236. <p class="last">Un modèle est la seule et définitive source de donnée à propos de
  237. vos données. Il contient les champs essentiels et les comportements
  238. des données que vous stockez. Django suit le <a class="reference" href="http://c2.com/cgi/wiki?DontRepeatYourself">Principe DRY</a>. Le
  239. but est de définir votre modèle de données dans un endroit et d'en
  240. faire dériver tout le reste automatiquement.</p>
  241. </div>
  242. <p>Dans notre simple appli de sondage, nous allons créer deux modèles:
  243. polls et choices. Un sondage est constitué d'une question et d'une
  244. date de publication. Un choix a deux champs: le libellé du choix et le
  245. nombre de votes pour ce choix. Chaque choix est associé à un sondage.</p>
  246. <p>Ces concepts sont représentés par de simples classes Python. Éditez le fichier
  247. <tt class="docutils literal"><span class="pre">polls/models.py</span></tt> pour qu'il ressemble à ça:</p>
  248. <pre class="literal-block">
  249. from django.db import models
  250. class Poll(models.Model):
  251. question = models.CharField(maxlength=200)
  252. pub_date = models.DateTimeField('Date de publication')
  253. class Choice(models.Model):
  254. poll = models.ForeignKey(Poll)
  255. choice = models.CharField(maxlength=200)
  256. votes = models.IntegerField()
  257. </pre>
  258. <p>Le code est clair et concis. Chaque modèle est représenté par une classe qui
  259. étend <tt class="docutils literal"><span class="pre">django.db.models.Model</span></tt>. Chaque molèle a un certain nombre d'attributs
  260. de classe, chacun représentant un champ de base de données dans le modèle.</p>
  261. <p>Chaque champ est représenté par l'instance d'une classe <tt class="docutils literal"><span class="pre">models.*Field</span></tt> -- par
  262. exemple, <tt class="docutils literal"><span class="pre">models.CharField</span></tt> pour les champs de chaîne de caractères et
  263. <tt class="docutils literal"><span class="pre">models.DateTimeField</span></tt> pour les dates/heures. Ceci décrit à Django quel type
  264. de données est contenu dans chaque champs.</p>
  265. <p>Le nom de chaque instance de <tt class="docutils literal"><span class="pre">models.*Field</span></tt> (par exemple <tt class="docutils literal"><span class="pre">question</span></tt> ou
  266. <tt class="docutils literal"><span class="pre">pub_date</span></tt> ) est le nom du champ, dans un format informatique. Vous utiliserez
  267. cette valeur dans votre code Python, et votre base de données l'utilisera comme
  268. un nom de colonne.</p>
  269. <p>Vous pouvez définir en premier argument facultatif <tt class="docutils literal"><span class="pre">Field</span></tt> un nom informel,
  270. plus facilement compréhensible par un lecteur humain. Celui-ci est utilisé dans
  271. des parties introspective de Django et il contribue aussi à la documentation du
  272. code. Si ce champ n'est pas fourni, Django utilisera alors le nom informatique.
  273. Dans cet exemple, nous avons seulement défini un nom informel pour
  274. <tt class="docutils literal"><span class="pre">Poll.pub_date</span></tt>. Pour tous les autres champs de ce modèle, le nom informatique
  275. du champs est suffisamment explicite pour rester lisible.</p>
  276. <p>Quelques classes <tt class="docutils literal"><span class="pre">*Field</span></tt> requièrent des éléments. <tt class="docutils literal"><span class="pre">CharField</span></tt>, par
  277. exemple, requiert que vous lui donniez une longueur maximale <tt class="docutils literal"><span class="pre">maxlength</span></tt>. Ce
  278. n'est pas seulement utilisé dans le schéma de la base de données, mais
  279. également dans la validation, comme nous le verrons bientôt.</p>
  280. <p>Enfin, notez que la relation est définie en utilisant <tt class="docutils literal"><span class="pre">models.ForeignKey</span></tt>. Ça
  281. dit à Django que chaque choix Choice est lié à un unique sondage Poll. Django
  282. supporte toutes les relations communes des bases de données: n vers 1, n vers m
  283. et 1 vers 1.</p>
  284. </div>
  285. <div class="section">
  286. <h1><a id="activation-des-mod-les" name="activation-des-mod-les">Activation des modèles</a></h1>
  287. <p>Ce petit bout de code de modèle donne à Django beaucoup d'informations. Avec
  288. lui, Django est capable de:</p>
  289. <blockquote>
  290. <ul class="simple">
  291. <li>Créer le schéma de base de données (les instructions <tt class="docutils literal"><span class="pre">CREATE</span> <span class="pre">TABLE</span></tt>)
  292. pour cette appli.</li>
  293. <li>Créer une API en Python d'accès à la base de données afin d'accéder aux
  294. objets Poll et Choice.</li>
  295. </ul>
  296. </blockquote>
  297. <p>Mais avant, nous avons besoin de dire à notre projet que l'application <tt class="docutils literal"><span class="pre">polls</span></tt>
  298. est installée.</p>
  299. <div class="admonition-philosophie admonition">
  300. <p class="first admonition-title">Philosophie</p>
  301. <p class="last">Les applis Django sont « pluggables » : Vous pouvez utiliser une appli dans
  302. de nombreux projets, et vous pouvez distribuer des applis, parce qu'elles ne
  303. doivent pas dépendre d'une installation Django donnée.</p>
  304. </div>
  305. <p>Éditez à nouveau le fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>, et changez l'option
  306. <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> pour inclure la chaîne <tt class="docutils literal"><span class="pre">'monsite.polls'</span></tt>. Ce qui devrait
  307. ressembler à ça:</p>
  308. <pre class="literal-block">
  309. INSTALLED_APPS = (
  310. 'django.contrib.auth',
  311. 'django.contrib.contenttypes',
  312. 'django.contrib.sessions',
  313. 'django.contrib.sites',
  314. 'monsite.polls'
  315. )
  316. </pre>
  317. <p>Maintenant Django sait que <tt class="docutils literal"><span class="pre">monsite</span></tt> inclue l'appli <tt class="docutils literal"><span class="pre">polls</span></tt>. Lançons une
  318. autre commande:</p>
  319. <pre class="literal-block">
  320. python manage.py sql polls
  321. </pre>
  322. <p>Vous devriez voir ce qui suit (les instructions SQL CREATE TABLE pour l'appli
  323. polls):</p>
  324. <pre class="literal-block">
  325. BEGIN;
  326. CREATE TABLE &quot;polls_poll&quot; (
  327. &quot;id&quot; serial NOT NULL PRIMARY KEY,
  328. &quot;question&quot; varchar(200) NOT NULL,
  329. &quot;pub_date&quot; timestamp with time zone NOT NULL
  330. );
  331. CREATE TABLE &quot;polls_choice&quot; (
  332. &quot;id&quot; serial NOT NULL PRIMARY KEY,
  333. &quot;poll_id&quot; integer NOT NULL REFERENCES &quot;polls_poll&quot; (&quot;id&quot;),
  334. &quot;choice&quot; varchar(200) NOT NULL,
  335. &quot;votes&quot; integer NOT NULL
  336. );
  337. COMMIT;
  338. </pre>
  339. <p>Notez ceci:</p>
  340. <blockquote>
  341. <ul class="simple">
  342. <li>Le nom des tables est généré automatiquement en combinant le nom de
  343. l'appli (<tt class="docutils literal"><span class="pre">polls</span></tt>) avec le nom en minuscule du modèle -- <tt class="docutils literal"><span class="pre">poll</span></tt> et
  344. <tt class="docutils literal"><span class="pre">choice</span></tt>. (Vous pouvez changer ce comportement.)</li>
  345. <li>Les clés primaires (IDs) sont ajoutées automatiquement. (Vous pouvez aussi
  346. le changer.)</li>
  347. <li>Par convention, Django ajoute <tt class="docutils literal"><span class="pre">&quot;_id&quot;</span></tt> à nom de champ de la clé
  348. étrangère. Oui, vous pouvez également le changer.</li>
  349. <li>La relation de la clé étrangère est faite explicitement par une clause
  350. <tt class="docutils literal"><span class="pre">REFERENCES</span></tt>.</li>
  351. <li>Le code est rédigé pour la base de données que vous employez, donc les
  352. types de champ spécifiques à chaque base de données, tel que
  353. <tt class="docutils literal"><span class="pre">auto_increment</span></tt> (MySQL), <tt class="docutils literal"><span class="pre">serial</span></tt> (PostgreSQL), ou
  354. <tt class="docutils literal"><span class="pre">integer</span> <span class="pre">primary</span> <span class="pre">key</span></tt> (SQLite) sont gérés pour vous automatiquement.
  355. Même chose pour les quotes de noms de champs -- par exemple, l'utilisation
  356. de doubles ou simples quotes. L'auteur de ce tutoriel utilise PostgreSQL,
  357. donc les traces d'exécution de l'exemple sont dans la syntaxe PostgreSQL.</li>
  358. <li>La commande <cite>sql</cite> ne lance en fait pas le code SQL dans votre base de
  359. données - il l'affiche juste à l'écran pour que vous puissiez voir quel
  360. code SQL est requis d'après Django. Si vous aviez voulu, nous auriez pu
  361. copier et coller ce code SQL dans l'invite interactive de votre base de
  362. données. Cependant, comme nous le verrons d'ici peu, Django fournit une
  363. moyen plus simple d'éxecuter le SQL dans la base de données.</li>
  364. </ul>
  365. </blockquote>
  366. <dl class="docutils">
  367. <dt>Si vous êtes intéressé, lancez aussi les commandes suivantes :</dt>
  368. <dd><ul class="first last simple">
  369. <li><tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">validate</span> <span class="pre">polls</span></tt> -- Vérifie s'il n'y a pas d'erreurs
  370. dans la construction de vos modèles.</li>
  371. <li><tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlinitialdata</span> <span class="pre">polls</span></tt> -- Affiche toutes les données
  372. initiales requises pour le framework d'administration de Django et pour
  373. vos modèles.</li>
  374. <li><tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlclear</span> <span class="pre">polls</span></tt> -- Affiche les instructions <tt class="docutils literal"><span class="pre">DROP</span>
  375. <span class="pre">TABLE</span></tt> nécessaires pour cette appli, selon les table qui existent déjà
  376. dans votre base de données (s'il y en a).</li>
  377. <li><tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlindexes</span> <span class="pre">polls</span></tt> -- Affiche les instructions <tt class="docutils literal"><span class="pre">CREATE</span>
  378. <span class="pre">INDEX</span></tt> pour cette appli.</li>
  379. <li><tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlall</span> <span class="pre">polls</span></tt> -- Une combinaison de tous les codes SQL
  380. des commandes 'sql', 'sqlinitialdata', et 'sqlindexes'.</li>
  381. </ul>
  382. </dd>
  383. </dl>
  384. <p>L'examen de la trace d'exécution de ces commandes peut vous aider à
  385. comprendre ce qui se passe en fait en bas-niveau.</p>
  386. <p>À présent, lancez à nouveau <tt class="docutils literal"><span class="pre">syncdb</span></tt> pour créer ces tables du modèles dans
  387. votre base de données:</p>
  388. <pre class="literal-block">
  389. python manage.py syncdb
  390. </pre>
  391. <p>La commande <tt class="docutils literal"><span class="pre">syncdb</span></tt> exécute le code sql de 'sqlall' dans votre base de
  392. données pour toutes les applis de <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> qui n'existent pas encore
  393. dans votre base de données. Ça crée toutes les tables, initie les données et
  394. indexes pour toutes les applis que vous avez ajouté dans votre projet depuis la
  395. dernière fois que vous avez lancé syncdb. <tt class="docutils literal"><span class="pre">syncdb</span></tt> peut être appelé aussi
  396. souvent que vous le souhaitez, et ça ne créera que les tables qui n'existaient
  397. pas auparavant.</p>
  398. <p>Lisez la <a class="reference" href="http://www.djangoproject.com/documentation/django_admin/">documentation de django-admin.py</a> pour des informations complètes sur
  399. ce que l'outil <tt class="docutils literal"><span class="pre">manage.py</span></tt> peut faire.</p>
  400. </div>
  401. <div class="section">
  402. <h1><a id="jouons-avec-l-api" name="jouons-avec-l-api">Jouons avec l'API</a></h1>
  403. <p>Maintenant, jetons un œil au shell Python interactif et jouons avec l'API libre
  404. que Django nous fournit. Pour invoquer le shell Python, utilisez cette
  405. commande:</p>
  406. <pre class="literal-block">
  407. python manage.py shell
  408. </pre>
  409. <p>Nous utilisons celle-ci au lieu de simplement taper « python » parce que
  410. <tt class="docutils literal"><span class="pre">manage.py</span></tt> définit l'environnement du projet pour vous. « Définir
  411. l'environnement » signifie deux choses:</p>
  412. <blockquote>
  413. <ul>
  414. <li><p class="first">Insertion de <tt class="docutils literal"><span class="pre">monsite</span></tt> dans <tt class="docutils literal"><span class="pre">sys.path</span></tt>. Par flexibilité, plusieurs
  415. parties de Django se référent aux projets à l'aide de la notation Python
  416. de chemins séparés par des points (par exemple, <cite>'monsite.polls.models'`</cite>
  417. ). Et pour que ça marche, le paquetage <tt class="docutils literal"><span class="pre">monsite</span></tt> doit être dans
  418. <tt class="docutils literal"><span class="pre">sys.path</span></tt>.</p>
  419. <p>Nous avons déjà vu un exemple de cela : l'option <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> est
  420. une liste de paquetages utilisant la notation de chemins séparés par des
  421. points.</p>
  422. </li>
  423. <li><p class="first">Définition de la variable d'environnement <tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE</span></tt>, qui
  424. indique à Django le chemin vers votre fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>.</p>
  425. </li>
  426. </ul>
  427. </blockquote>
  428. <div class="admonition-outrepasser-manage-py admonition">
  429. <p class="first admonition-title">Outrepasser manage.py</p>
  430. <p>Si vous préférez ne pas utiliser <tt class="docutils literal"><span class="pre">manage.py</span></tt>, pas de problème. Vérifiez
  431. juste que <tt class="docutils literal"><span class="pre">monsite</span></tt> est à la racine du path Python (c'est-à-dire, <tt class="docutils literal"><span class="pre">import</span>
  432. <span class="pre">monsite</span></tt> fonctionne) et définissez la variable d'environnement
  433. <tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE</span></tt> à <tt class="docutils literal"><span class="pre">monsite.settings</span></tt>.</p>
  434. <p class="last">Pour plus d'informations sur tout cela, lisez la <a class="reference" href="http://www.djangoproject.com/documentation/django_admin/">documentation de
  435. django-admin.py</a>.</p>
  436. </div>
  437. <p>Une fois que vous êtes dans le shell, explorez l'API pour la base de données:</p>
  438. <pre class="literal-block">
  439. # Importe les classes de modèle que nous venons d'écrire.
  440. &gt;&gt;&gt; from monsite.polls.models import Poll, Choice
  441. # Aucun sondage n'est dans le système pour l'instant.
  442. &gt;&gt;&gt; Poll.objects.all()
  443. []
  444. # Crée un nouveau sondage Poll.
  445. &gt;&gt;&gt; from datetime import datetime
  446. &gt;&gt;&gt; p = Poll(question=&quot;Quoi de neuf ?&quot;, pub_date=datetime.now())
  447. # Sauvegarde l'objet dans la base de données.
  448. # Vous devez appeler save() explicitement.
  449. &gt;&gt;&gt; p.save()
  450. # Maintenant il a un ID. Notez que ça pourrait afficher &quot;1L&quot; au lieu de &quot;1&quot;,
  451. # cela dépend de la base de données que vous utilisez. Ce n'est pas un bug ;
  452. # ça signifie juste que le backend de votre base de données préfère
  453. # retourner les entiers comme des objets de type entiers longs en Python.
  454. &gt;&gt;&gt; p.id
  455. 1
  456. # Accède aux colonnes de base de données via les attributs Python.
  457. &gt;&gt;&gt; p.question
  458. &quot;Quoi de neuf ?&quot;
  459. &gt;&gt;&gt; p.pub_date
  460. datetime.datetime(2005, 7, 15, 12, 00, 53)
  461. # Change les valeurs en modifiant les attributs, puis en appelant save().
  462. &gt;&gt;&gt; p.pub_date = datetime(2005, 4, 1, 0, 0)
  463. &gt;&gt;&gt; p.save()
  464. # objects.all() affiche tous les sondages de la base de données.
  465. &gt;&gt;&gt; Poll.objects.all()
  466. [&lt;Poll: Poll object&gt;]
  467. </pre>
  468. <p>Attendez une minute. <tt class="docutils literal"><span class="pre">&lt;Poll:</span> <span class="pre">Poll</span> <span class="pre">object&gt;</span></tt> est, à vrai dire, une
  469. représentation qui n'apporte rien sur l'objet. Corrigeons cela en éditant le
  470. modèle des sondages (dans le fichier <tt class="docutils literal"><span class="pre">polls/models.py</span></tt>) et en ajoutant une
  471. méthode <tt class="docutils literal"><span class="pre">__str__()</span></tt> aux classes <tt class="docutils literal"><span class="pre">Poll</span></tt> et <tt class="docutils literal"><span class="pre">Choice</span></tt>:</p>
  472. <pre class="literal-block">
  473. class Poll(models.Model):
  474. # ...
  475. def __str__(self):
  476. return self.question
  477. class Choice(models.Model):
  478. # ...
  479. def __str__(self):
  480. return self.choice
  481. </pre>
  482. <p>Il est important d'ajouter les méthodes <tt class="docutils literal"><span class="pre">__str__()</span></tt> dans vos modèles, pas
  483. seulement pour votre propre bien-être lorsque vous utilisez la console
  484. interactive, mais aussi parce que les représentations d'objets sont utilisées à
  485. travers l'interface d'administration auto-générée de Django.</p>
  486. <p>Notez que ce sont des méthodes standards de Python. Ajoutons une méthode perso,
  487. juste pour la démo:</p>
  488. <pre class="literal-block">
  489. import datetime
  490. # ...
  491. class Poll(models.Model):
  492. # ...
  493. def was_published_today(self):
  494. return self.pub_date.date() == datetime.date.today()
  495. </pre>
  496. <p>Notez l'ajout de <tt class="docutils literal"><span class="pre">import</span> <span class="pre">datetime</span></tt> pour référencer le module standard de
  497. Python <tt class="docutils literal"><span class="pre">datetime</span></tt>.</p>
  498. <p>Revenons au shell Python interactif en lançant à nouveau <tt class="docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span>
  499. <span class="pre">shell</span></tt>:</p>
  500. <pre class="literal-block">
  501. &gt;&gt;&gt; from monsite.polls.models import Poll, Choice
  502. # Vérifie que notre nouvelle méthode __str__() fonctionne.
  503. &gt;&gt;&gt; Poll.objects.all()
  504. [&lt;Poll: Quoi de neuf ?&gt;]
  505. # Django fournit une riche API de recherche dans la base de données qui est
  506. # entièrement gérée par des arguments mot-clés.
  507. &gt;&gt;&gt; Poll.objects.filter(id=1)
  508. [&lt;Poll: Quoi de neuf ?&gt;]
  509. &gt;&gt;&gt; Poll.objects.filter(question__startswith='Quoi')
  510. [&lt;Poll: Quoi de neuf ?&gt;]
  511. # Récupére le sondage dont l'année est 2005. Bien sûr, si vous suivez ce
  512. # tutoriel dans une autre année, remplacez par la valeur appropriée.
  513. &gt;&gt;&gt; Poll.objects.get(pub_date__year=2005)
  514. &lt;Poll: Quoi de neuf ?&gt;
  515. &gt;&gt;&gt; Poll.objects.get(id=2)
  516. Traceback (most recent call last):
  517. ...
  518. DoesNotExist: Poll matching query does not exist.
  519. # La recherche par clé primaire est le cas le plus courant, donc Django
  520. # fournit un raccourci pour les recherches exactes sur clé primaire.
  521. # Ce qui suit est identique à Poll.objects.get(id=1).
  522. &gt;&gt;&gt; Poll.objects.get(pk=1)
  523. &lt;Poll: Quoi de neuf ?&gt;
  524. # Vérifie que notre méthode perso fonctionne.
  525. &gt;&gt;&gt; p = Poll.objects.get(pk=1)
  526. &gt;&gt;&gt; p.was_published_today()
  527. False
  528. # Donne une liste de choix Choice au sondage Poll. L'appel à create
  529. # construit un nouvel objet choice, fait l'instruction INSERT , ajoute le
  530. # choix dans l'ensemble des choix disponibles et retourne le nouvel objet
  531. # Choice.
  532. &gt;&gt;&gt; p = Poll.objects.get(pk=1)
  533. &gt;&gt;&gt; p.choice_set.create(choice='Pas grand chose', votes=0)
  534. &lt;Choice: Pas grand chose&gt;
  535. &gt;&gt;&gt; p.choice_set.create(choice='Le ciel', votes=0)
  536. &lt;Choice: Le ciel&gt;
  537. &gt;&gt;&gt; c = p.choice_set.create(choice='Toujours en train de coder', votes=0)
  538. # Les objets Choice ont une API d'accès aux objets Poll qui leur sont liés.
  539. &gt;&gt;&gt; c.poll
  540. &lt;Poll: Quoi de neuf ?&gt;
  541. # Et vice-versa: les objets Poll ont accès aux objets Choice.
  542. &gt;&gt;&gt; p.choice_set.all()
  543. [&lt;Choice: Pas grand chose&gt;, &lt;Choice: Le ciel&gt;, &lt;Choice: Toujours en train de coder&gt;]
  544. &gt;&gt;&gt; p.choice_set.count()
  545. 3
  546. # L'API suit automatiquement les relations aussi loin que vous en avez
  547. # besoin. Utilisez les doubles underscores pour séparer les relations.
  548. # Ça fonctionne sur autant de niveaux de profonteur que vous voulez. Il n'y
  549. # a pas de limite. Trouve tous les choix Choice pour n'importe quel sondage
  550. # dont le pub_date est 2005.
  551. &gt;&gt;&gt; Choice.objects.filter(poll__pub_date__year=2005)
  552. [&lt;Choice: Pas grand chose&gt;, &lt;Choice: Le ciel&gt;, &lt;Choice: Toujours en train de coder&gt;]
  553. # Supprimons un des choix. Utilisez delete() pour se faire.
  554. &gt;&gt;&gt; c = p.choice_set.filter(choice__startswith='Toujours en train')
  555. &gt;&gt;&gt; c.delete()
  556. </pre>
  557. <p>Pour les détails complets au sujet de l'API de la base de données, lisez notre
  558. <a class="reference" href="http://www.djangoproject.com/documentation/db_api/">référence de l'API de base de données</a>.</p>
  559. <p>Quand vous vous serez familiarisé avec l'API, lisez la <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-2-exploration-de-l-interface-d-admin-auto-generee/">partie 2 de ce
  560. tutoriel</a> pour voir le fonctionnement de l'interface d'administration
  561. automatique de Django.</p>
  562. <p>Vous pouvez maintenant retourner à la <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-traduction-francaise-de-la-documentation-de-django-le-framework-web-python/">page d'accueil des traductions de la
  563. documentation de Django</a>.</p>
  564. <p>Cette traduction correspond à la révision 3589 (post 0.95).</p>
  565. </div>