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.

index.html 47KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. <!doctype html>
  2. <html lang=fr>
  3. <head>
  4. <!-- Always define the charset before the title -->
  5. <meta charset=utf-8>
  6. <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 — Biologeek — David Larlet</title>
  7. <!-- Define a viewport to mobile devices to use - telling the browser to assume that the page is as wide as the device (width=device-width) and setting the initial page zoom level to be 1 (initial-scale=1.0) -->
  8. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  9. <!-- Fake favicon, to avoid extra request to the server -->
  10. <link rel="icon" href="data:;base64,iVBORw0KGgo=">
  11. <link type="application/atom+xml" rel="alternate" title="Feed" href="/david/log/" />
  12. <link rel="manifest" href="/manifest.json">
  13. <link rel="stylesheet" href="/static/david/css/larlet-david-_J6Rv.css" data-instant-track />
  14. <noscript>
  15. <style type="text/css">
  16. /* Otherwise fonts are loaded by JS for faster initial rendering. See scripts at the bottom. */
  17. body {
  18. font-family: 'EquityTextB', serif;
  19. }
  20. h1, h2, h3, h4, h5, h6, time, nav a, nav a:link, nav a:visited {
  21. font-family: 'EquityCapsB', sans-serif;
  22. font-variant: normal;
  23. }
  24. </style>
  25. </noscript>
  26. <!-- Canonical URL for SEO purposes -->
  27. <link rel="canonical" href="https://larlet.fr/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-1-initialisation-creation-des-modeles-et-api-de-la-base-de-donnees">
  28. </head>
  29. <body>
  30. <div>
  31. <header>
  32. <nav>
  33. <p>
  34. <small>
  35. Je suis <a href="/david/" title="Profil public">David Larlet</a>, <a href="/david/pro/" title="Activité professionnelle">artisan</a> du web qui vous <a href="/david/pro/accompagnement/" title="Activité d’accompagnement">accompagne</a><span class="more-infos"> dans l’acquisition de savoirs pour concevoir des <a href="/david/pro/produits-essentiels/" title="Qu’est-ce qu’un produit essentiel ?">produits essentiels</a></span>. <span class="more-more-infos">Discutons ensemble d’une <a href="/david/pro/devis/" title="En savoir plus">non-demande de devis</a>.</span> Je partage ici mes <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et <a href="/david/correspondances/2017/" title="Lettres hebdomadaires">correspondances</a>.
  36. </small>
  37. </p>
  38. </nav>
  39. </header>
  40. <section>
  41. <h1 property="schema:name">Rédaction de votre première appli Django, partie 1 : Initialisation, création des modèles et API de la base de données</h1>
  42. <article typeof="schema:BlogPosting">
  43. <div property="schema:articleBody">
  44. <img src="/static/david/biologeek/images/logos/django.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
  45. <p>Apprenons par l'exemple.</p>
  46. <p>À travers ce tutoriel, nous aborderons la création d'une application basique de
  47. sondage.</p>
  48. <p>Cela consistera en deux parties:</p>
  49. <blockquote>
  50. <ul class="simple">
  51. <li>Un site public qui permet aux internautes de voir les sondages et de
  52. voter.</li>
  53. <li>Un site d'administration qui vous permet d'ajouter, modifier et supprimer
  54. un sondage.</li>
  55. </ul>
  56. </blockquote>
  57. <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
  58. si Django est installé en lançant l'interpréteur interactif Python et en tapant
  59. <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
  60. bien installé.</p>
  61. <div class="section">
  62. <h1><a id="cr-ation-d-un-projet" name="cr-ation-d-un-projet">Création d'un projet</a></h1>
  63. <p>Si vous utilisez Django pour la première fois, vous devrez faire attention à
  64. quelques options de la configuration initiale. En effet, vous aurez besoin
  65. d'auto-générer du code qui met en place un <em>projet</em> Django -- une configuration
  66. propre à chaque instance de Django, incluant la configuration de la base de
  67. données, les options spécifiques à Django et la configuration spécifique aux
  68. applications.</p>
  69. <p>En ligne de commande, faites <tt class="docutils literal"><span class="pre">cd</span></tt> d'un répertoire où vous aimeriez conserver
  70. 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>.
  71. Ceci va créer un répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt> dans le répertoire courant.</p>
  72. <p>(<tt class="docutils literal"><span class="pre">django-admin.py</span></tt> devrait être dans votre path système si vous avez installé
  73. 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
  74. 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
  75. sous-répertoire de votre installation Python. Faites un lien symbolique de
  76. <tt class="docutils literal"><span class="pre">django-admin.py</span></tt> quelque part dans votre path, typiquement
  77. <tt class="docutils literal"><span class="pre">/usr/local/bin</span></tt>.)</p>
  78. <div class="admonition-o-devrait-on-mettre-le-code admonition">
  79. <p class="first admonition-title">Où devrait-on mettre le code ?</p>
  80. <p>Si vous avez connu le PHP, vous êtes probablement habitué à mettre le code
  81. dans le répertoire de documents du server Web (dans un endroit comme
  82. <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
  83. mettre du code python dans votre répertoire de documents du serveur Web
  84. parce que vous prennez le risquez que l'on puisse voir votre code depuis le
  85. Web. Ce n'est pas bon d'un point de vue de la sécurité.</p>
  86. <p class="last">Mettez votre code dans un répertoire <strong>à l'extérieur</strong> du répertoire de
  87. documents, par exemple <tt class="docutils literal"><span class="pre">/home/moncode</span></tt>.</p>
  88. </div>
  89. <p>Jetons un œil à ce que <tt class="docutils literal"><span class="pre">startproject</span></tt> a créé:</p>
  90. <pre class="literal-block">
  91. monsite/
  92. __init__.py
  93. manage.py
  94. settings.py
  95. urls.py
  96. </pre>
  97. <p>Ces fichiers sont:</p>
  98. <blockquote>
  99. <ul class="simple">
  100. <li><tt class="docutils literal"><span class="pre">__init__.py</span></tt>: Un fichier vide que dit à Python que ce répertoire
  101. 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
  102. paquetages</a> dans la documentation officielle de Python si vous êtes
  103. débutant en Python.)</li>
  104. <li><tt class="docutils literal"><span class="pre">manage.py</span></tt>: Un outil en ligne de commande que vous permet d'intéragir
  105. avec ce projet Django de différentes manières.</li>
  106. <li><tt class="docutils literal"><span class="pre">settings.py</span></tt>: Fichier de configuration de ce projet Django.</li>
  107. <li><tt class="docutils literal"><span class="pre">urls.py</span></tt>: Les déclarations d'URLs pour ce projet Django ; il s'agit
  108. d'une « table des matières » de votre site géré par Django.</li>
  109. </ul>
  110. </blockquote>
  111. <div class="section">
  112. <h2><a id="le-serveur-de-d-veloppement" name="le-serveur-de-d-veloppement">Le serveur de développement</a></h2>
  113. <p>Vérifions que tout ceci fonctionne. Placez-vous dans le répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt>,
  114. 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>
  115. <span class="pre">runserver</span></tt>. Vous verrez la trace d'exécution suivante dans votre terminal:</p>
  116. <pre class="literal-block">
  117. Validating models...
  118. 0 errors found.
  119. Django version 0.95, using settings 'monsite.settings'
  120. Development server is running at http://127.0.0.1:8000/
  121. Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
  122. </pre>
  123. <p>Vous avez démarré le serveur de développement de Django, un serveur web léger
  124. écrit entièrement en Python. Nous l'avons intégré à Django pour que vous
  125. puissiez développer des choses rapidement, sans avoir à vous occuper de la
  126. configuration d'un serveur de production -- tel Apache -- jusqu'à ce que
  127. vous soyez prêt à passer en production.</p>
  128. <p>À présent, c'est le bon moment pour noter : N'utilisez PAS ce serveur
  129. pour quoi que ce soit ressemblant à un environnement de production. C'est
  130. seulement destiné à une utilisation pendant le développement
  131. (Nous concevons des frameworks Web, pas des serveurs Web).</p>
  132. <p>Maintenant que le serveur tourne, visitez la page
  133. <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
  134. « Welcome to Django », dans un agréable bleu clair pastel. Ça marche !</p>
  135. <div class="admonition-changement-du-port admonition">
  136. <p class="first admonition-title">Changement du port</p>
  137. <p>Par défaut, la commande <tt class="docutils literal"><span class="pre">runserver</span></tt> démarre le serveur de
  138. développement sur le port 8000. Si vous voulez changer le port du
  139. serveur, passez-le en tant qu'argument à la ligne de commande. Par
  140. exemple, cette commande démarre le serveur sur le port 8080:</p>
  141. <pre class="literal-block">
  142. python manage.py runserver 8080
  143. </pre>
  144. <p class="last">Une documentation complète sur le serveur de développement se
  145. trouve dans la <a class="reference" href="http://www.djangoproject.com/documentation/django_admin/">documentation de django-admin</a>.</p>
  146. </div>
  147. <p></div>
  148. <div class="section">
  149. <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>
  150. <p>Maintenant, éditez le fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>. C'est un module Python
  151. normal avec des variables de module représentant les options de
  152. configuration de Django. Modifiez ces options pour qu'elles correspondent à vos
  153. paramètres de connexion à votre base de données:</p>
  154. <blockquote></p>
  155. <ul class="simple">
  156. <li><tt class="docutils literal"><span class="pre">DATABASE_ENGINE</span></tt> -- Au choix parmi 'postgresql', 'mysql' ou 'sqlite3'.
  157. D'autres viendront bientôt.</li>
  158. <li><tt class="docutils literal"><span class="pre">DATABASE_NAME</span></tt> -- Le nom de votre base de données, ou le
  159. chemin complet (absolu) du fichier de base de données si vous
  160. utilisez SQLite.</li>
  161. <li><tt class="docutils literal"><span class="pre">DATABASE_USER</span></tt> -- Le nom d'utilisateur de la base de données
  162. (non utilisé pour SQLite).</li>
  163. <li><tt class="docutils literal"><span class="pre">DATABASE_PASSWORD</span></tt> -- Le mot de passe de la base de données
  164. (non utilisé pour SQLite).</li>
  165. <li><tt class="docutils literal"><span class="pre">DATABASE_HOST</span></tt> -- Le nom d'hôte sur lequel est votre base de
  166. données. Laissez une chaîne vide si votre serveur de base de
  167. données est sur la même machine physique (non utilisé pour SQLite).</li>
  168. </ul>
  169. <p></blockquote>
  170. <div class="admonition-note admonition">
  171. <p class="first admonition-title">Note</p>
  172. <p class="last">Si vous utilisez PostgreSQL ou MySQL, assurez-vous d'avoir créé
  173. une base de données à cette étape. Faites cela avec « <tt class="docutils literal"><span class="pre">CREATE</span>
  174. <span class="pre">DATABASE</span> <span class="pre">base_de_donnees;</span></tt> » à l'invite du client interactif de
  175. votre base de données.</p></p>
  176. <p></div>
  177. <p>Pendant que vous éditez <tt class="docutils literal"><span class="pre">settings.py</span></tt>, notez la présence de l'option
  178. <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> vers la fin du fichier. Cette variable contient le
  179. nom de toutes les applications Django qui sont activées dans cette
  180. instance de Django. Les applis peuvent être utilisées dans de
  181. multiples projets, et vous pouvez les empaqueter et les distribuer
  182. pour que d'autres les utilisent dans leurs projets.</p>
  183. <p>Par défaut, <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> contient les applis suivantes, toutes
  184. sont fournies avec Django:</p>
  185. <blockquote>
  186. <ul class="simple">
  187. <li><tt class="docutils literal"><span class="pre">django.contrib.auth</span></tt> -- Un système d'authentification.</li></p>
  188. <li><tt class="docutils literal"><span class="pre">django.contrib.contenttypes</span></tt> -- Un framework pour les types
  189. de contenu.</li>
  190. <li><tt class="docutils literal"><span class="pre">django.contrib.sessions</span></tt> -- Un framework gérant les sessions.</li>
  191. <li><tt class="docutils literal"><span class="pre">django.contrib.sites</span></tt> -- Un framework pour gérer plusieurs sites
  192. avec une seule installation de Django.</li>
  193. <p></ul>
  194. </blockquote>
  195. <p>Ces applications sont incluses par défaut car elles conviennent pour
  196. la plupart des cas.</p>
  197. <p>Chacune de ces applications entraîne l'utilisation d'au moins une
  198. table de base de données, par conséquent, nous avons besoin de créer
  199. ces tables dans la base de données avant que nous puissions les
  200. utiliser. Pour ce faire, lancez la commande suivante:</p></p>
  201. <pre class="literal-block">
  202. python manage.py syncdb
  203. </pre>
  204. <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
  205. toutes les tables de base de données nécessaires selon la
  206. configuration de la base de données dans votre fichier
  207. <tt class="docutils literal"><span class="pre">settings.py</span></tt>. Vous verrez un message pour chaque table que ça crée,
  208. et vous aurez une invite vous demandant si vous aimeriez créer un
  209. compte superutilisateur pour le système d'authentification. Continuez
  210. et faites-le.</p>
  211. <p>Si cela vous intéresse, exécutez le client intéractif de votre base de
  212. 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
  213. <tt class="docutils literal"><span class="pre">.schema</span></tt> (SQLite) pour afficher les tables que Django a créées.</p>
  214. <div class="admonition-pour-les-minimalistes admonition">
  215. <p class="first admonition-title">Pour les minimalistes</p>
  216. <p class="last">Comme nous avons dit plus haut, les applications par défaut sont
  217. incluses pour les cas courants, mais tout le monde n'en a pas
  218. forcément besoin. Si vous n'avez pas besoin d'une ou plusieurs
  219. d'entre elles (voire toutes), libre à vous de commenter ou supprimer
  220. la ou les lignes appropriées dans <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> avant de
  221. 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
  222. les applis qui sont dans <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt>.</p>
  223. </div>
  224. <p></div>
  225. </div>
  226. <div class="section">
  227. <h1><a id="cr-ation-de-mod-les" name="cr-ation-de-mod-les">Création de modèles</a></h1>
  228. <p>Maintenant que notre environnement -- un &quot;projet&quot; -- est initialisé,
  229. vous pouvez commencer à travailler.</p>
  230. <p>Chaque application que vous écrivez dans Django constitue un paquetage
  231. Python, quelque part dans votre <a class="reference" href="http://docs.python.org/tut/node8.html#SECTION008110000000000000000">Python path</a>, qui suit une certaine
  232. convention. Django est fourni avec un utilitaire que génère
  233. automatiquement la structure basique du répertoire d'une appli, vous
  234. pouvez donc vous focaliser sur la rédaction du code plutôt que sur la
  235. création des répertoires.</p>
  236. <div class="admonition-projets-contre-applis admonition">
  237. <p class="first admonition-title">Projets contre applis</p></p>
  238. <p class="last">Quelle est la différence entre un projet et une appli ? Une appli
  239. est une application web que fait quelque chose -- par exemple, un
  240. système de weblog, une base d'enregistrements publics ou une simple
  241. appli de sondage. Un projet est un ensemble de paramètres et
  242. d'applications pour un site Web particulier. Un projet peut
  243. contenir plusieurs applis. Une appli peut être dans plusieurs projets.</p>
  244. <p></div>
  245. <p>Dans ce tutoriel, nous allons créer notre appli de sondage dans le
  246. répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt>, pour plus de simplicité. En conséquence,
  247. l'appli sera couplée au projet -- c'est-à-dire que le code Python dans
  248. l'appli de sondage réfèrera à <tt class="docutils literal"><span class="pre">monsite.polls</span></tt>.
  249. Plus tard dans le tutoriel, nous discuterons du découplage de vos
  250. applications pour les distribuer indépendamment.</p>
  251. <p>Pour créer votre appli, assurez-vous que vous êtes dans le répertoire
  252. <tt class="docutils literal"><span class="pre">monsite</span></tt> et tapez la commande:</p>
  253. <pre class="literal-block">
  254. python manage.py startapp polls
  255. </pre></p>
  256. <p>Cela créera un répertoire <tt class="docutils literal"><span class="pre">polls</span></tt>, qui est décrit comme suit:</p>
  257. <pre class="literal-block">
  258. polls/
  259. __init__.py
  260. models.py
  261. views.py
  262. </pre>
  263. <p>Cette structure du répertoire va accueillir l'application de sondage.</p>
  264. <p>La première étape dans la rédaction d'une appli Web utilisant la base
  265. de données est de définir vos modèles -- essentiellement, la
  266. description de votre base de données, avec des méta-données additionnelles.</p>
  267. <div class="admonition-philosophie admonition">
  268. <p class="first admonition-title">Philosophie</p>
  269. <p class="last">Un modèle est la seule et définitive source de donnée à propos de
  270. vos données. Il contient les champs essentiels et les comportements
  271. des données que vous stockez. Django suit le <a class="reference" href="http://c2.com/cgi/wiki?DontRepeatYourself">Principe DRY</a>. Le
  272. but est de définir votre modèle de données dans un endroit et d'en
  273. faire dériver tout le reste automatiquement.</p>
  274. </div>
  275. <p>Dans notre simple appli de sondage, nous allons créer deux modèles:
  276. polls et choices. Un sondage est constitué d'une question et d'une
  277. date de publication. Un choix a deux champs: le libellé du choix et le
  278. nombre de votes pour ce choix. Chaque choix est associé à un sondage.</p>
  279. <p>Ces concepts sont représentés par de simples classes Python. Éditez le fichier
  280. <tt class="docutils literal"><span class="pre">polls/models.py</span></tt> pour qu'il ressemble à ça:</p>
  281. <pre class="literal-block">
  282. from django.db import models
  283. class Poll(models.Model):
  284. question = models.CharField(maxlength=200)
  285. pub_date = models.DateTimeField('Date de publication')
  286. class Choice(models.Model):
  287. poll = models.ForeignKey(Poll)
  288. choice = models.CharField(maxlength=200)
  289. votes = models.IntegerField()
  290. </pre>
  291. <p>Le code est clair et concis. Chaque modèle est représenté par une classe qui
  292. étend <tt class="docutils literal"><span class="pre">django.db.models.Model</span></tt>. Chaque molèle a un certain nombre d'attributs
  293. de classe, chacun représentant un champ de base de données dans le modèle.</p>
  294. <p>Chaque champ est représenté par l'instance d'une classe <tt class="docutils literal"><span class="pre">models.*Field</span></tt> -- par
  295. exemple, <tt class="docutils literal"><span class="pre">models.CharField</span></tt> pour les champs de chaîne de caractères et
  296. <tt class="docutils literal"><span class="pre">models.DateTimeField</span></tt> pour les dates/heures. Ceci décrit à Django quel type
  297. de données est contenu dans chaque champs.</p>
  298. <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
  299. <tt class="docutils literal"><span class="pre">pub_date</span></tt> ) est le nom du champ, dans un format informatique. Vous utiliserez
  300. cette valeur dans votre code Python, et votre base de données l'utilisera comme
  301. un nom de colonne.</p>
  302. <p>Vous pouvez définir en premier argument facultatif <tt class="docutils literal"><span class="pre">Field</span></tt> un nom informel,
  303. plus facilement compréhensible par un lecteur humain. Celui-ci est utilisé dans
  304. des parties introspective de Django et il contribue aussi à la documentation du
  305. code. Si ce champ n'est pas fourni, Django utilisera alors le nom informatique.
  306. Dans cet exemple, nous avons seulement défini un nom informel pour
  307. <tt class="docutils literal"><span class="pre">Poll.pub_date</span></tt>. Pour tous les autres champs de ce modèle, le nom informatique
  308. du champs est suffisamment explicite pour rester lisible.</p>
  309. <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
  310. exemple, requiert que vous lui donniez une longueur maximale <tt class="docutils literal"><span class="pre">maxlength</span></tt>. Ce
  311. n'est pas seulement utilisé dans le schéma de la base de données, mais
  312. également dans la validation, comme nous le verrons bientôt.</p>
  313. <p>Enfin, notez que la relation est définie en utilisant <tt class="docutils literal"><span class="pre">models.ForeignKey</span></tt>. Ça
  314. dit à Django que chaque choix Choice est lié à un unique sondage Poll. Django
  315. supporte toutes les relations communes des bases de données: n vers 1, n vers m
  316. et 1 vers 1.</p>
  317. </div>
  318. <div class="section">
  319. <h1><a id="activation-des-mod-les" name="activation-des-mod-les">Activation des modèles</a></h1>
  320. <p>Ce petit bout de code de modèle donne à Django beaucoup d'informations. Avec
  321. lui, Django est capable de:</p>
  322. <blockquote>
  323. <ul class="simple">
  324. <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>)
  325. pour cette appli.</li>
  326. <li>Créer une API en Python d'accès à la base de données afin d'accéder aux
  327. objets Poll et Choice.</li>
  328. </ul>
  329. </blockquote>
  330. <p>Mais avant, nous avons besoin de dire à notre projet que l'application <tt class="docutils literal"><span class="pre">polls</span></tt>
  331. est installée.</p>
  332. <div class="admonition-philosophie admonition">
  333. <p class="first admonition-title">Philosophie</p>
  334. <p class="last">Les applis Django sont « pluggables » : Vous pouvez utiliser une appli dans
  335. de nombreux projets, et vous pouvez distribuer des applis, parce qu'elles ne
  336. doivent pas dépendre d'une installation Django donnée.</p>
  337. </div>
  338. <p>Éditez à nouveau le fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>, et changez l'option
  339. <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
  340. ressembler à ça:</p>
  341. <pre class="literal-block">
  342. INSTALLED_APPS = (
  343. 'django.contrib.auth',
  344. 'django.contrib.contenttypes',
  345. 'django.contrib.sessions',
  346. 'django.contrib.sites',
  347. 'monsite.polls'
  348. )
  349. </pre>
  350. <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
  351. autre commande:</p>
  352. <pre class="literal-block">
  353. python manage.py sql polls
  354. </pre>
  355. <p>Vous devriez voir ce qui suit (les instructions SQL CREATE TABLE pour l'appli
  356. polls):</p>
  357. <pre class="literal-block">
  358. BEGIN;
  359. CREATE TABLE &quot;polls_poll&quot; (
  360. &quot;id&quot; serial NOT NULL PRIMARY KEY,
  361. &quot;question&quot; varchar(200) NOT NULL,
  362. &quot;pub_date&quot; timestamp with time zone NOT NULL
  363. );
  364. CREATE TABLE &quot;polls_choice&quot; (
  365. &quot;id&quot; serial NOT NULL PRIMARY KEY,
  366. &quot;poll_id&quot; integer NOT NULL REFERENCES &quot;polls_poll&quot; (&quot;id&quot;),
  367. &quot;choice&quot; varchar(200) NOT NULL,
  368. &quot;votes&quot; integer NOT NULL
  369. );
  370. COMMIT;
  371. </pre>
  372. <p>Notez ceci:</p>
  373. <blockquote>
  374. <ul class="simple">
  375. <li>Le nom des tables est généré automatiquement en combinant le nom de
  376. 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
  377. <tt class="docutils literal"><span class="pre">choice</span></tt>. (Vous pouvez changer ce comportement.)</li>
  378. <li>Les clés primaires (IDs) sont ajoutées automatiquement. (Vous pouvez aussi
  379. le changer.)</li>
  380. <li>Par convention, Django ajoute <tt class="docutils literal"><span class="pre">&quot;_id&quot;</span></tt> à nom de champ de la clé
  381. étrangère. Oui, vous pouvez également le changer.</li>
  382. <li>La relation de la clé étrangère est faite explicitement par une clause
  383. <tt class="docutils literal"><span class="pre">REFERENCES</span></tt>.</li>
  384. <li>Le code est rédigé pour la base de données que vous employez, donc les
  385. types de champ spécifiques à chaque base de données, tel que
  386. <tt class="docutils literal"><span class="pre">auto_increment</span></tt> (MySQL), <tt class="docutils literal"><span class="pre">serial</span></tt> (PostgreSQL), ou
  387. <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.
  388. Même chose pour les quotes de noms de champs -- par exemple, l'utilisation
  389. de doubles ou simples quotes. L'auteur de ce tutoriel utilise PostgreSQL,
  390. donc les traces d'exécution de l'exemple sont dans la syntaxe PostgreSQL.</li>
  391. <li>La commande <cite>sql</cite> ne lance en fait pas le code SQL dans votre base de
  392. données - il l'affiche juste à l'écran pour que vous puissiez voir quel
  393. code SQL est requis d'après Django. Si vous aviez voulu, nous auriez pu
  394. copier et coller ce code SQL dans l'invite interactive de votre base de
  395. données. Cependant, comme nous le verrons d'ici peu, Django fournit une
  396. moyen plus simple d'éxecuter le SQL dans la base de données.</li>
  397. </ul>
  398. </blockquote>
  399. <dl class="docutils">
  400. <dt>Si vous êtes intéressé, lancez aussi les commandes suivantes :</dt>
  401. <dd><ul class="first last simple">
  402. <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
  403. dans la construction de vos modèles.</li>
  404. <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
  405. initiales requises pour le framework d'administration de Django et pour
  406. vos modèles.</li>
  407. <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>
  408. <span class="pre">TABLE</span></tt> nécessaires pour cette appli, selon les table qui existent déjà
  409. dans votre base de données (s'il y en a).</li>
  410. <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>
  411. <span class="pre">INDEX</span></tt> pour cette appli.</li>
  412. <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
  413. des commandes 'sql', 'sqlinitialdata', et 'sqlindexes'.</li>
  414. </ul>
  415. </dd>
  416. </dl>
  417. <p>L'examen de la trace d'exécution de ces commandes peut vous aider à
  418. comprendre ce qui se passe en fait en bas-niveau.</p>
  419. <p>À présent, lancez à nouveau <tt class="docutils literal"><span class="pre">syncdb</span></tt> pour créer ces tables du modèles dans
  420. votre base de données:</p>
  421. <pre class="literal-block">
  422. python manage.py syncdb
  423. </pre>
  424. <p>La commande <tt class="docutils literal"><span class="pre">syncdb</span></tt> exécute le code sql de 'sqlall' dans votre base de
  425. données pour toutes les applis de <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> qui n'existent pas encore
  426. dans votre base de données. Ça crée toutes les tables, initie les données et
  427. indexes pour toutes les applis que vous avez ajouté dans votre projet depuis la
  428. dernière fois que vous avez lancé syncdb. <tt class="docutils literal"><span class="pre">syncdb</span></tt> peut être appelé aussi
  429. souvent que vous le souhaitez, et ça ne créera que les tables qui n'existaient
  430. pas auparavant.</p>
  431. <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
  432. ce que l'outil <tt class="docutils literal"><span class="pre">manage.py</span></tt> peut faire.</p>
  433. </div>
  434. <div class="section">
  435. <h1><a id="jouons-avec-l-api" name="jouons-avec-l-api">Jouons avec l'API</a></h1>
  436. <p>Maintenant, jetons un œil au shell Python interactif et jouons avec l'API libre
  437. que Django nous fournit. Pour invoquer le shell Python, utilisez cette
  438. commande:</p>
  439. <pre class="literal-block">
  440. python manage.py shell
  441. </pre>
  442. <p>Nous utilisons celle-ci au lieu de simplement taper « python » parce que
  443. <tt class="docutils literal"><span class="pre">manage.py</span></tt> définit l'environnement du projet pour vous. « Définir
  444. l'environnement » signifie deux choses:</p>
  445. <blockquote>
  446. <ul>
  447. <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
  448. parties de Django se référent aux projets à l'aide de la notation Python
  449. de chemins séparés par des points (par exemple, <cite>'monsite.polls.models'`</cite>
  450. ). Et pour que ça marche, le paquetage <tt class="docutils literal"><span class="pre">monsite</span></tt> doit être dans
  451. <tt class="docutils literal"><span class="pre">sys.path</span></tt>.</p>
  452. <p>Nous avons déjà vu un exemple de cela : l'option <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> est
  453. une liste de paquetages utilisant la notation de chemins séparés par des
  454. points.</p>
  455. </li>
  456. <li><p class="first">Définition de la variable d'environnement <tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE</span></tt>, qui
  457. indique à Django le chemin vers votre fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>.</p>
  458. </li>
  459. </ul>
  460. </blockquote>
  461. <div class="admonition-outrepasser-manage-py admonition">
  462. <p class="first admonition-title">Outrepasser manage.py</p>
  463. <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
  464. 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>
  465. <span class="pre">monsite</span></tt> fonctionne) et définissez la variable d'environnement
  466. <tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE</span></tt> à <tt class="docutils literal"><span class="pre">monsite.settings</span></tt>.</p>
  467. <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
  468. django-admin.py</a>.</p>
  469. </div>
  470. <p>Une fois que vous êtes dans le shell, explorez l'API pour la base de données:</p>
  471. <pre class="literal-block">
  472. # Importe les classes de modèle que nous venons d'écrire.
  473. &gt;&gt;&gt; from monsite.polls.models import Poll, Choice
  474. # Aucun sondage n'est dans le système pour l'instant.
  475. &gt;&gt;&gt; Poll.objects.all()
  476. []
  477. # Crée un nouveau sondage Poll.
  478. &gt;&gt;&gt; from datetime import datetime
  479. &gt;&gt;&gt; p = Poll(question=&quot;Quoi de neuf ?&quot;, pub_date=datetime.now())
  480. # Sauvegarde l'objet dans la base de données.
  481. # Vous devez appeler save() explicitement.
  482. &gt;&gt;&gt; p.save()
  483. # Maintenant il a un ID. Notez que ça pourrait afficher &quot;1L&quot; au lieu de &quot;1&quot;,
  484. # cela dépend de la base de données que vous utilisez. Ce n'est pas un bug ;
  485. # ça signifie juste que le backend de votre base de données préfère
  486. # retourner les entiers comme des objets de type entiers longs en Python.
  487. &gt;&gt;&gt; p.id
  488. 1
  489. # Accède aux colonnes de base de données via les attributs Python.
  490. &gt;&gt;&gt; p.question
  491. &quot;Quoi de neuf ?&quot;
  492. &gt;&gt;&gt; p.pub_date
  493. datetime.datetime(2005, 7, 15, 12, 00, 53)
  494. # Change les valeurs en modifiant les attributs, puis en appelant save().
  495. &gt;&gt;&gt; p.pub_date = datetime(2005, 4, 1, 0, 0)
  496. &gt;&gt;&gt; p.save()
  497. # objects.all() affiche tous les sondages de la base de données.
  498. &gt;&gt;&gt; Poll.objects.all()
  499. [&lt;Poll: Poll object&gt;]
  500. </pre>
  501. <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
  502. représentation qui n'apporte rien sur l'objet. Corrigeons cela en éditant le
  503. modèle des sondages (dans le fichier <tt class="docutils literal"><span class="pre">polls/models.py</span></tt>) et en ajoutant une
  504. 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>
  505. <pre class="literal-block">
  506. class Poll(models.Model):
  507. # ...
  508. def __str__(self):
  509. return self.question
  510. class Choice(models.Model):
  511. # ...
  512. def __str__(self):
  513. return self.choice
  514. </pre>
  515. <p>Il est important d'ajouter les méthodes <tt class="docutils literal"><span class="pre">__str__()</span></tt> dans vos modèles, pas
  516. seulement pour votre propre bien-être lorsque vous utilisez la console
  517. interactive, mais aussi parce que les représentations d'objets sont utilisées à
  518. travers l'interface d'administration auto-générée de Django.</p>
  519. <p>Notez que ce sont des méthodes standards de Python. Ajoutons une méthode perso,
  520. juste pour la démo:</p>
  521. <pre class="literal-block">
  522. import datetime
  523. # ...
  524. class Poll(models.Model):
  525. # ...
  526. def was_published_today(self):
  527. return self.pub_date.date() == datetime.date.today()
  528. </pre>
  529. <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
  530. Python <tt class="docutils literal"><span class="pre">datetime</span></tt>.</p>
  531. <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>
  532. <span class="pre">shell</span></tt>:</p>
  533. <pre class="literal-block">
  534. &gt;&gt;&gt; from monsite.polls.models import Poll, Choice
  535. # Vérifie que notre nouvelle méthode __str__() fonctionne.
  536. &gt;&gt;&gt; Poll.objects.all()
  537. [&lt;Poll: Quoi de neuf ?&gt;]
  538. # Django fournit une riche API de recherche dans la base de données qui est
  539. # entièrement gérée par des arguments mot-clés.
  540. &gt;&gt;&gt; Poll.objects.filter(id=1)
  541. [&lt;Poll: Quoi de neuf ?&gt;]
  542. &gt;&gt;&gt; Poll.objects.filter(question__startswith='Quoi')
  543. [&lt;Poll: Quoi de neuf ?&gt;]
  544. # Récupére le sondage dont l'année est 2005. Bien sûr, si vous suivez ce
  545. # tutoriel dans une autre année, remplacez par la valeur appropriée.
  546. &gt;&gt;&gt; Poll.objects.get(pub_date__year=2005)
  547. &lt;Poll: Quoi de neuf ?&gt;
  548. &gt;&gt;&gt; Poll.objects.get(id=2)
  549. Traceback (most recent call last):
  550. ...
  551. DoesNotExist: Poll matching query does not exist.
  552. # La recherche par clé primaire est le cas le plus courant, donc Django
  553. # fournit un raccourci pour les recherches exactes sur clé primaire.
  554. # Ce qui suit est identique à Poll.objects.get(id=1).
  555. &gt;&gt;&gt; Poll.objects.get(pk=1)
  556. &lt;Poll: Quoi de neuf ?&gt;
  557. # Vérifie que notre méthode perso fonctionne.
  558. &gt;&gt;&gt; p = Poll.objects.get(pk=1)
  559. &gt;&gt;&gt; p.was_published_today()
  560. False
  561. # Donne une liste de choix Choice au sondage Poll. L'appel à create
  562. # construit un nouvel objet choice, fait l'instruction INSERT , ajoute le
  563. # choix dans l'ensemble des choix disponibles et retourne le nouvel objet
  564. # Choice.
  565. &gt;&gt;&gt; p = Poll.objects.get(pk=1)
  566. &gt;&gt;&gt; p.choice_set.create(choice='Pas grand chose', votes=0)
  567. &lt;Choice: Pas grand chose&gt;
  568. &gt;&gt;&gt; p.choice_set.create(choice='Le ciel', votes=0)
  569. &lt;Choice: Le ciel&gt;
  570. &gt;&gt;&gt; c = p.choice_set.create(choice='Toujours en train de coder', votes=0)
  571. # Les objets Choice ont une API d'accès aux objets Poll qui leur sont liés.
  572. &gt;&gt;&gt; c.poll
  573. &lt;Poll: Quoi de neuf ?&gt;
  574. # Et vice-versa: les objets Poll ont accès aux objets Choice.
  575. &gt;&gt;&gt; p.choice_set.all()
  576. [&lt;Choice: Pas grand chose&gt;, &lt;Choice: Le ciel&gt;, &lt;Choice: Toujours en train de coder&gt;]
  577. &gt;&gt;&gt; p.choice_set.count()
  578. 3
  579. # L'API suit automatiquement les relations aussi loin que vous en avez
  580. # besoin. Utilisez les doubles underscores pour séparer les relations.
  581. # Ça fonctionne sur autant de niveaux de profonteur que vous voulez. Il n'y
  582. # a pas de limite. Trouve tous les choix Choice pour n'importe quel sondage
  583. # dont le pub_date est 2005.
  584. &gt;&gt;&gt; Choice.objects.filter(poll__pub_date__year=2005)
  585. [&lt;Choice: Pas grand chose&gt;, &lt;Choice: Le ciel&gt;, &lt;Choice: Toujours en train de coder&gt;]
  586. # Supprimons un des choix. Utilisez delete() pour se faire.
  587. &gt;&gt;&gt; c = p.choice_set.filter(choice__startswith='Toujours en train')
  588. &gt;&gt;&gt; c.delete()
  589. </pre>
  590. <p>Pour les détails complets au sujet de l'API de la base de données, lisez notre
  591. <a class="reference" href="http://www.djangoproject.com/documentation/db_api/">référence de l'API de base de données</a>.</p>
  592. <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
  593. tutoriel</a> pour voir le fonctionnement de l'interface d'administration
  594. automatique de Django.</p>
  595. <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
  596. documentation de Django</a>.</p>
  597. <p>Cette traduction correspond à la révision 3589 (post 0.95).</p>
  598. </div>
  599. </div>
  600. </article>
  601. <footer>
  602. <h6 property="schema:datePublished">— 17/06/2006</h6>
  603. </footer>
  604. </section>
  605. <section>
  606. <div>
  607. <h3>Articles peut-être en rapport</h3>
  608. <ul>
  609. <li><a href="/david/biologeek/archives/20060815-le-langage-de-template-django-pour-les-auteurs-de-templates/" title="Accès à Le langage de template Django : Pour les auteurs de templates">Le langage de template Django : Pour les auteurs de templates</a></li>
  610. <li><a href="/david/biologeek/archives/20060715-comparaison-de-turbogears-et-django-deux-frameworks-web-python/" title="Accès à Comparaison de TurboGears et Django, deux frameworks web Python">Comparaison de TurboGears et Django, deux frameworks web Python</a></li>
  611. <li><a href="/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques/" title="Accès à Rédaction de votre première appli Django, partie 4 : Conception d&#39;un formulaire et vues génériques">Rédaction de votre première appli Django, partie 4 : Conception d&#39;un formulaire et vues génériques</a></li>
  612. </ul>
  613. </div>
  614. </section>
  615. <section>
  616. <div id="comments">
  617. <h3>Commentaires</h3>
  618. <div class="comment" typeof="schema:UserComments">
  619. <p class="comment-meta">
  620. <span class="comment-author" property="schema:creator">Paolo</span> le <span class="comment-date" property="schema:commentTime">17/06/2006</span> :
  621. </p>
  622. <div class="comment-content" property="schema:commentText">
  623. <p>Django's tutorial part one translated in French.. simply fantastic :-)<br />
  624. Great news, keep up the good work!</p>
  625. </div>
  626. </div>
  627. <div class="comment" typeof="schema:UserComments">
  628. <p class="comment-meta">
  629. <span class="comment-author" property="schema:creator">David</span> le <span class="comment-date" property="schema:commentTime">20/06/2006</span> :
  630. </p>
  631. <div class="comment-content" property="schema:commentText">
  632. <p>Très bon travail, j'attends la suite avec impatience ! ;-)</p>
  633. </div>
  634. </div>
  635. <div class="comment" typeof="schema:UserComments">
  636. <p class="comment-meta">
  637. <span class="comment-author" property="schema:creator">Phil</span> le <span class="comment-date" property="schema:commentTime">19/07/2006</span> :
  638. </p>
  639. <div class="comment-content" property="schema:commentText">
  640. <p>Petite faute de typo, on créé le projet monsite, mais dans les exemples, on utilise mysite</p>
  641. </div>
  642. </div>
  643. <div class="comment" typeof="schema:UserComments">
  644. <p class="comment-meta">
  645. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">19/07/2006</span> :
  646. </p>
  647. <div class="comment-content" property="schema:commentText">
  648. <p>Bien vu, corrigé :)</p>
  649. </div>
  650. </div>
  651. <div class="comment" typeof="schema:UserComments">
  652. <p class="comment-meta">
  653. <span class="comment-author" property="schema:creator">Flipper</span> le <span class="comment-date" property="schema:commentTime">05/08/2006</span> :
  654. </p>
  655. <div class="comment-content" property="schema:commentText">
  656. <p>Petite faute de frappe, dans le petit paragraphe &quot;Projets contre applis&quot; il y a d'écrit &quot;un base d'enregistrement&quot;</p>
  657. </div>
  658. </div>
  659. <div class="comment" typeof="schema:UserComments">
  660. <p class="comment-meta">
  661. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">05/08/2006</span> :
  662. </p>
  663. <div class="comment-content" property="schema:commentText">
  664. <p>Ok, merci c'est corrigé !</p>
  665. </div>
  666. </div>
  667. <div class="comment" typeof="schema:UserComments">
  668. <p class="comment-meta">
  669. <span class="comment-author" property="schema:creator">ark</span> le <span class="comment-date" property="schema:commentTime">11/01/2007</span> :
  670. </p>
  671. <div class="comment-content" property="schema:commentText">
  672. <p>joli travail, merci :)</p>
  673. </div>
  674. </div>
  675. <div class="comment" typeof="schema:UserComments">
  676. <p class="comment-meta">
  677. <span class="comment-author" property="schema:creator">Bastien</span> le <span class="comment-date" property="schema:commentTime">16/01/2007</span> :
  678. </p>
  679. <div class="comment-content" property="schema:commentText">
  680. <p>Note : Il est possible de générer automatiquement le fichier models.py depuis une base de donnée existante (définie dans monsite\settings.py) en exécutant la commande &quot;python manage.py inspectdb &gt; monapp/models.py&quot; à partir du répertoire du site...Cependant, d'après mon expérience, pour mysql il faudra créer soi-même les clés étrangères selon ce modèle :<br />
  681. <br />
  682. class AuthMessage(models.Model):<br />
  683. id = models.IntegerField(primary_key=True)<br />
  684. user = models.ForeignKey(AuthUser)<br />
  685. message = models.TextField()<br />
  686. class Meta:<br />
  687. db_table = 'auth_message'<br />
  688. <br />
  689. Et modifier le fichier settings.py afin que (dans ce cas par exemple) la classe AuthUser soit déclarée dans le fichier AVANT la classe AuthMessage.</p>
  690. </div>
  691. </div>
  692. <div class="comment" typeof="schema:UserComments">
  693. <p class="comment-meta">
  694. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">16/01/2007</span> :
  695. </p>
  696. <div class="comment-content" property="schema:commentText">
  697. <p>Tu peux aussi déclarer tes Key/Field sous la forme de strings, auquel cas l'ordre n'importe pas, par exemple ici :<br />
  698. <br />
  699. user = models.ForeignKey('AuthUser')</p>
  700. </div>
  701. </div>
  702. <div class="comment" typeof="schema:UserComments">
  703. <p class="comment-meta">
  704. <span class="comment-author" property="schema:creator">[JO-JOJO]</span> le <span class="comment-date" property="schema:commentTime">07/05/2007</span> :
  705. </p>
  706. <div class="comment-content" property="schema:commentText">
  707. <p>Bonjour,<br />
  708. <br />
  709. Merci encore pour tous ces tuto vraiment bien expliqués !<br />
  710. <br />
  711. J'ai fait des petites recherches pour le champ de type ImageField, car j'aimerai lui donné un chemin d'accès en fonction d'une catégorie spécifique !!<br />
  712. <br />
  713. voilà donc comment j'ai fait cela : <br />
  714. categorie = models.ForeignKey(CategoriePhoto)<br />
  715. ImageField(upload_to='photos/%(categorie)s') <br />
  716. <br />
  717. Mais ceci ne marche pas ... pourquoi ? ca me créer un dossier qui s'appele &quot; categorie)s &quot; !!! bizarrreeee !<br />
  718. <br />
  719. Merci d'avance<br />
  720. <br />
  721. Joakim<br />
  722. </p>
  723. </div>
  724. </div>
  725. <div class="comment" typeof="schema:UserComments">
  726. <p class="comment-meta">
  727. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">07/05/2007</span> :
  728. </p>
  729. <div class="comment-content" property="schema:commentText">
  730. <p>Normal, il faut que tu traites la chaîne de caractère upload_to comme une chaîne de caractères python. Pour l'utilisation comme un dictionnaire, tu peux consulter ce billet :<br />
  731. <a href="https://larlet.fr/david/biologeek/archives/20060121-formatage-des-chaines-de-caracteres-en-python/" title="https://larlet.fr/david/biologeek/archives/20060121-formatage-des-chaines-de-caracteres-en-python/" rel="nofollow">www.biologeek.com/journal...</a><br />
  732. <br />
  733. Pour faire court, il faudrait mettre :<br />
  734. ImageField(upload_to='photos/%(categorie)s' % {'categorie': nom-de-ta-catégorie})<br />
  735. <br />
  736. Bon courage dans ton apprentissage de Django :-).</p>
  737. </div>
  738. </div>
  739. <div class="comment" typeof="schema:UserComments">
  740. <p class="comment-meta">
  741. <span class="comment-author" property="schema:creator">Poipoi</span> le <span class="comment-date" property="schema:commentTime">06/11/2008</span> :
  742. </p>
  743. <div class="comment-content" property="schema:commentText">
  744. <p>J&#39;ai eu un soucis lors de l&#39;activation du modele; il y a eu l&#39;erreur suivante:</p>
  745. <p>&quot;__init__() got an unexpected keyword argument &#39;maxlength&#39; &quot;</p>
  746. <p>J&#39;ai du remplacer par &quot;maxlength&quot; par &quot;max_length&quot; et ça a marché.</p>
  747. <p>config: <br />django 1<br />debian etch<br />bdd mysql</p>
  748. </div>
  749. </div>
  750. </div>
  751. </section>
  752. <footer>
  753. <nav>
  754. <p>
  755. <small>
  756. Je réponds quasiment toujours aux <a href="m&#x61;ilto:d&#x61;vid%40l&#x61;rlet&#46;fr" title="Envoyer un email">emails</a> (<a href="/david/signature/" title="Ma signature actuelle avec possibilité de chiffrement">signés</a>) et vous pouvez me rencontrer à Montréal. <span class="more-infos">N’hésitez pas à <a href="/david/log/" title="Être tenu informé des mises à jour">vous abonner</a> pour être tenu informé des publications récentes.</span>
  757. </small>
  758. </p>
  759. </nav>
  760. </footer>
  761. </div>
  762. <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
  763. <script data-no-instant>InstantClick.init()</script>
  764. </body>
  765. </html>