|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
- <!doctype html>
- <html lang=fr>
- <head>
- <!-- Always define the charset before the title -->
- <meta charset=utf-8>
- <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>
- <!-- 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) -->
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
- <!-- Fake favicon, to avoid extra request to the server -->
- <link rel="icon" href="data:;base64,iVBORw0KGgo=">
- <link type="application/atom+xml" rel="alternate" title="Feed" href="/david/log/" />
- <link rel="manifest" href="/manifest.json">
-
- <link rel="stylesheet" href="/static/david/css/larlet-david-_J6Rv.css" data-instant-track />
-
- <noscript>
- <style type="text/css">
- /* Otherwise fonts are loaded by JS for faster initial rendering. See scripts at the bottom. */
- body {
- font-family: 'EquityTextB', serif;
- }
- h1, h2, h3, h4, h5, h6, time, nav a, nav a:link, nav a:visited {
- font-family: 'EquityCapsB', sans-serif;
- font-variant: normal;
- }
- </style>
- </noscript>
-
- <!-- Canonical URL for SEO purposes -->
- <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">
-
- </head>
- <body>
- <div>
-
- <header>
- <nav>
- <p>
- <small>
- 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>.
- </small>
- </p>
- </nav>
- </header>
-
-
- <section>
- <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>
- <article typeof="schema:BlogPosting">
- <div property="schema:articleBody">
- <img src="/static/david/biologeek/images/logos/django.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
- <p>Apprenons par l'exemple.</p>
-
- <p>À travers ce tutoriel, nous aborderons la création d'une application basique de
- sondage.</p>
-
- <p>Cela consistera en deux parties:</p>
-
- <blockquote>
- <ul class="simple">
- <li>Un site public qui permet aux internautes de voir les sondages et de
- voter.</li>
- <li>Un site d'administration qui vous permet d'ajouter, modifier et supprimer
- un sondage.</li>
- </ul>
- </blockquote>
-
- <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
- si Django est installé en lançant l'interpréteur interactif Python et en tapant
- <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
- bien installé.</p>
-
- <div class="section">
- <h1><a id="cr-ation-d-un-projet" name="cr-ation-d-un-projet">Création d'un projet</a></h1>
- <p>Si vous utilisez Django pour la première fois, vous devrez faire attention à
- quelques options de la configuration initiale. En effet, vous aurez besoin
- d'auto-générer du code qui met en place un <em>projet</em> Django -- une configuration
- propre à chaque instance de Django, incluant la configuration de la base de
- données, les options spécifiques à Django et la configuration spécifique aux
- applications.</p>
- <p>En ligne de commande, faites <tt class="docutils literal"><span class="pre">cd</span></tt> d'un répertoire où vous aimeriez conserver
- 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>.
- Ceci va créer un répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt> dans le répertoire courant.</p>
-
- <p>(<tt class="docutils literal"><span class="pre">django-admin.py</span></tt> devrait être dans votre path système si vous avez installé
- 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
- 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
- sous-répertoire de votre installation Python. Faites un lien symbolique de
- <tt class="docutils literal"><span class="pre">django-admin.py</span></tt> quelque part dans votre path, typiquement
- <tt class="docutils literal"><span class="pre">/usr/local/bin</span></tt>.)</p>
-
- <div class="admonition-o-devrait-on-mettre-le-code admonition">
- <p class="first admonition-title">Où devrait-on mettre le code ?</p>
- <p>Si vous avez connu le PHP, vous êtes probablement habitué à mettre le code
- dans le répertoire de documents du server Web (dans un endroit comme
- <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
- mettre du code python dans votre répertoire de documents du serveur Web
- parce que vous prennez le risquez que l'on puisse voir votre code depuis le
- Web. Ce n'est pas bon d'un point de vue de la sécurité.</p>
- <p class="last">Mettez votre code dans un répertoire <strong>à l'extérieur</strong> du répertoire de
- documents, par exemple <tt class="docutils literal"><span class="pre">/home/moncode</span></tt>.</p>
- </div>
- <p>Jetons un œil à ce que <tt class="docutils literal"><span class="pre">startproject</span></tt> a créé:</p>
-
- <pre class="literal-block">
- monsite/
- __init__.py
- manage.py
- settings.py
- urls.py
- </pre>
- <p>Ces fichiers sont:</p>
- <blockquote>
- <ul class="simple">
- <li><tt class="docutils literal"><span class="pre">__init__.py</span></tt>: Un fichier vide que dit à Python que ce répertoire
- 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
- paquetages</a> dans la documentation officielle de Python si vous êtes
- débutant en Python.)</li>
- <li><tt class="docutils literal"><span class="pre">manage.py</span></tt>: Un outil en ligne de commande que vous permet d'intéragir
- avec ce projet Django de différentes manières.</li>
- <li><tt class="docutils literal"><span class="pre">settings.py</span></tt>: Fichier de configuration de ce projet Django.</li>
-
- <li><tt class="docutils literal"><span class="pre">urls.py</span></tt>: Les déclarations d'URLs pour ce projet Django ; il s'agit
- d'une « table des matières » de votre site géré par Django.</li>
- </ul>
- </blockquote>
- <div class="section">
- <h2><a id="le-serveur-de-d-veloppement" name="le-serveur-de-d-veloppement">Le serveur de développement</a></h2>
- <p>Vérifions que tout ceci fonctionne. Placez-vous dans le répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt>,
- 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>
- <span class="pre">runserver</span></tt>. Vous verrez la trace d'exécution suivante dans votre terminal:</p>
-
- <pre class="literal-block">
- Validating models...
- 0 errors found.
-
- Django version 0.95, using settings 'monsite.settings'
- Development server is running at http://127.0.0.1:8000/
- Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
- </pre>
- <p>Vous avez démarré le serveur de développement de Django, un serveur web léger
- écrit entièrement en Python. Nous l'avons intégré à Django pour que vous
- puissiez développer des choses rapidement, sans avoir à vous occuper de la
- configuration d'un serveur de production -- tel Apache -- jusqu'à ce que
- vous soyez prêt à passer en production.</p>
- <p>À présent, c'est le bon moment pour noter : N'utilisez PAS ce serveur
- pour quoi que ce soit ressemblant à un environnement de production. C'est
- seulement destiné à une utilisation pendant le développement
- (Nous concevons des frameworks Web, pas des serveurs Web).</p>
- <p>Maintenant que le serveur tourne, visitez la page
- <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
- « Welcome to Django », dans un agréable bleu clair pastel. Ça marche !</p>
- <div class="admonition-changement-du-port admonition">
- <p class="first admonition-title">Changement du port</p>
- <p>Par défaut, la commande <tt class="docutils literal"><span class="pre">runserver</span></tt> démarre le serveur de
- développement sur le port 8000. Si vous voulez changer le port du
- serveur, passez-le en tant qu'argument à la ligne de commande. Par
- exemple, cette commande démarre le serveur sur le port 8080:</p>
-
- <pre class="literal-block">
- python manage.py runserver 8080
- </pre>
- <p class="last">Une documentation complète sur le serveur de développement se
- trouve dans la <a class="reference" href="http://www.djangoproject.com/documentation/django_admin/">documentation de django-admin</a>.</p>
- </div>
-
- <p></div>
- <div class="section">
- <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>
- <p>Maintenant, éditez le fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>. C'est un module Python
- normal avec des variables de module représentant les options de
- configuration de Django. Modifiez ces options pour qu'elles correspondent à vos
- paramètres de connexion à votre base de données:</p>
- <blockquote></p>
- <ul class="simple">
- <li><tt class="docutils literal"><span class="pre">DATABASE_ENGINE</span></tt> -- Au choix parmi 'postgresql', 'mysql' ou 'sqlite3'.
- D'autres viendront bientôt.</li>
- <li><tt class="docutils literal"><span class="pre">DATABASE_NAME</span></tt> -- Le nom de votre base de données, ou le
- chemin complet (absolu) du fichier de base de données si vous
- utilisez SQLite.</li>
- <li><tt class="docutils literal"><span class="pre">DATABASE_USER</span></tt> -- Le nom d'utilisateur de la base de données
- (non utilisé pour SQLite).</li>
- <li><tt class="docutils literal"><span class="pre">DATABASE_PASSWORD</span></tt> -- Le mot de passe de la base de données
- (non utilisé pour SQLite).</li>
-
- <li><tt class="docutils literal"><span class="pre">DATABASE_HOST</span></tt> -- Le nom d'hôte sur lequel est votre base de
- données. Laissez une chaîne vide si votre serveur de base de
- données est sur la même machine physique (non utilisé pour SQLite).</li>
- </ul>
-
- <p></blockquote>
- <div class="admonition-note admonition">
- <p class="first admonition-title">Note</p>
- <p class="last">Si vous utilisez PostgreSQL ou MySQL, assurez-vous d'avoir créé
- une base de données à cette étape. Faites cela avec « <tt class="docutils literal"><span class="pre">CREATE</span>
- <span class="pre">DATABASE</span> <span class="pre">base_de_donnees;</span></tt> » à l'invite du client interactif de
- votre base de données.</p></p>
- <p></div>
- <p>Pendant que vous éditez <tt class="docutils literal"><span class="pre">settings.py</span></tt>, notez la présence de l'option
- <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> vers la fin du fichier. Cette variable contient le
- nom de toutes les applications Django qui sont activées dans cette
- instance de Django. Les applis peuvent être utilisées dans de
- multiples projets, et vous pouvez les empaqueter et les distribuer
- pour que d'autres les utilisent dans leurs projets.</p>
- <p>Par défaut, <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> contient les applis suivantes, toutes
- sont fournies avec Django:</p>
- <blockquote>
- <ul class="simple">
- <li><tt class="docutils literal"><span class="pre">django.contrib.auth</span></tt> -- Un système d'authentification.</li></p>
- <li><tt class="docutils literal"><span class="pre">django.contrib.contenttypes</span></tt> -- Un framework pour les types
- de contenu.</li>
-
- <li><tt class="docutils literal"><span class="pre">django.contrib.sessions</span></tt> -- Un framework gérant les sessions.</li>
-
- <li><tt class="docutils literal"><span class="pre">django.contrib.sites</span></tt> -- Un framework pour gérer plusieurs sites
- avec une seule installation de Django.</li>
-
- <p></ul>
- </blockquote>
- <p>Ces applications sont incluses par défaut car elles conviennent pour
- la plupart des cas.</p>
- <p>Chacune de ces applications entraîne l'utilisation d'au moins une
- table de base de données, par conséquent, nous avons besoin de créer
- ces tables dans la base de données avant que nous puissions les
- utiliser. Pour ce faire, lancez la commande suivante:</p></p>
- <pre class="literal-block">
- python manage.py syncdb
- </pre>
-
- <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
- toutes les tables de base de données nécessaires selon la
- configuration de la base de données dans votre fichier
- <tt class="docutils literal"><span class="pre">settings.py</span></tt>. Vous verrez un message pour chaque table que ça crée,
- et vous aurez une invite vous demandant si vous aimeriez créer un
- compte superutilisateur pour le système d'authentification. Continuez
- et faites-le.</p>
-
- <p>Si cela vous intéresse, exécutez le client intéractif de votre base de
- 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
-
- <tt class="docutils literal"><span class="pre">.schema</span></tt> (SQLite) pour afficher les tables que Django a créées.</p>
-
- <div class="admonition-pour-les-minimalistes admonition">
- <p class="first admonition-title">Pour les minimalistes</p>
- <p class="last">Comme nous avons dit plus haut, les applications par défaut sont
- incluses pour les cas courants, mais tout le monde n'en a pas
- forcément besoin. Si vous n'avez pas besoin d'une ou plusieurs
- d'entre elles (voire toutes), libre à vous de commenter ou supprimer
- la ou les lignes appropriées dans <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> avant de
- 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
- les applis qui sont dans <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt>.</p>
-
- </div>
-
- <p></div>
- </div>
- <div class="section">
- <h1><a id="cr-ation-de-mod-les" name="cr-ation-de-mod-les">Création de modèles</a></h1>
- <p>Maintenant que notre environnement -- un "projet" -- est initialisé,
- vous pouvez commencer à travailler.</p>
- <p>Chaque application que vous écrivez dans Django constitue un paquetage
- Python, quelque part dans votre <a class="reference" href="http://docs.python.org/tut/node8.html#SECTION008110000000000000000">Python path</a>, qui suit une certaine
- convention. Django est fourni avec un utilitaire que génère
- automatiquement la structure basique du répertoire d'une appli, vous
- pouvez donc vous focaliser sur la rédaction du code plutôt que sur la
- création des répertoires.</p>
- <div class="admonition-projets-contre-applis admonition">
- <p class="first admonition-title">Projets contre applis</p></p>
- <p class="last">Quelle est la différence entre un projet et une appli ? Une appli
- est une application web que fait quelque chose -- par exemple, un
- système de weblog, une base d'enregistrements publics ou une simple
- appli de sondage. Un projet est un ensemble de paramètres et
- d'applications pour un site Web particulier. Un projet peut
- contenir plusieurs applis. Une appli peut être dans plusieurs projets.</p>
-
- <p></div>
- <p>Dans ce tutoriel, nous allons créer notre appli de sondage dans le
- répertoire <tt class="docutils literal"><span class="pre">monsite</span></tt>, pour plus de simplicité. En conséquence,
- l'appli sera couplée au projet -- c'est-à-dire que le code Python dans
- l'appli de sondage réfèrera à <tt class="docutils literal"><span class="pre">monsite.polls</span></tt>.
- Plus tard dans le tutoriel, nous discuterons du découplage de vos
- applications pour les distribuer indépendamment.</p>
- <p>Pour créer votre appli, assurez-vous que vous êtes dans le répertoire
- <tt class="docutils literal"><span class="pre">monsite</span></tt> et tapez la commande:</p>
- <pre class="literal-block">
- python manage.py startapp polls
- </pre></p>
- <p>Cela créera un répertoire <tt class="docutils literal"><span class="pre">polls</span></tt>, qui est décrit comme suit:</p>
-
- <pre class="literal-block">
- polls/
- __init__.py
- models.py
- views.py
- </pre>
-
- <p>Cette structure du répertoire va accueillir l'application de sondage.</p>
-
- <p>La première étape dans la rédaction d'une appli Web utilisant la base
- de données est de définir vos modèles -- essentiellement, la
- description de votre base de données, avec des méta-données additionnelles.</p>
-
- <div class="admonition-philosophie admonition">
- <p class="first admonition-title">Philosophie</p>
- <p class="last">Un modèle est la seule et définitive source de donnée à propos de
- vos données. Il contient les champs essentiels et les comportements
- des données que vous stockez. Django suit le <a class="reference" href="http://c2.com/cgi/wiki?DontRepeatYourself">Principe DRY</a>. Le
- but est de définir votre modèle de données dans un endroit et d'en
- faire dériver tout le reste automatiquement.</p>
-
- </div>
-
- <p>Dans notre simple appli de sondage, nous allons créer deux modèles:
- polls et choices. Un sondage est constitué d'une question et d'une
- date de publication. Un choix a deux champs: le libellé du choix et le
- nombre de votes pour ce choix. Chaque choix est associé à un sondage.</p>
-
- <p>Ces concepts sont représentés par de simples classes Python. Éditez le fichier
- <tt class="docutils literal"><span class="pre">polls/models.py</span></tt> pour qu'il ressemble à ça:</p>
-
- <pre class="literal-block">
- from django.db import models
-
- class Poll(models.Model):
- question = models.CharField(maxlength=200)
- pub_date = models.DateTimeField('Date de publication')
-
- class Choice(models.Model):
- poll = models.ForeignKey(Poll)
- choice = models.CharField(maxlength=200)
- votes = models.IntegerField()
- </pre>
-
- <p>Le code est clair et concis. Chaque modèle est représenté par une classe qui
- étend <tt class="docutils literal"><span class="pre">django.db.models.Model</span></tt>. Chaque molèle a un certain nombre d'attributs
- de classe, chacun représentant un champ de base de données dans le modèle.</p>
-
- <p>Chaque champ est représenté par l'instance d'une classe <tt class="docutils literal"><span class="pre">models.*Field</span></tt> -- par
- exemple, <tt class="docutils literal"><span class="pre">models.CharField</span></tt> pour les champs de chaîne de caractères et
-
- <tt class="docutils literal"><span class="pre">models.DateTimeField</span></tt> pour les dates/heures. Ceci décrit à Django quel type
- de données est contenu dans chaque champs.</p>
-
- <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
- <tt class="docutils literal"><span class="pre">pub_date</span></tt> ) est le nom du champ, dans un format informatique. Vous utiliserez
- cette valeur dans votre code Python, et votre base de données l'utilisera comme
- un nom de colonne.</p>
-
- <p>Vous pouvez définir en premier argument facultatif <tt class="docutils literal"><span class="pre">Field</span></tt> un nom informel,
- plus facilement compréhensible par un lecteur humain. Celui-ci est utilisé dans
- des parties introspective de Django et il contribue aussi à la documentation du
- code. Si ce champ n'est pas fourni, Django utilisera alors le nom informatique.
- Dans cet exemple, nous avons seulement défini un nom informel pour
-
- <tt class="docutils literal"><span class="pre">Poll.pub_date</span></tt>. Pour tous les autres champs de ce modèle, le nom informatique
- du champs est suffisamment explicite pour rester lisible.</p>
-
- <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
- exemple, requiert que vous lui donniez une longueur maximale <tt class="docutils literal"><span class="pre">maxlength</span></tt>. Ce
- n'est pas seulement utilisé dans le schéma de la base de données, mais
- également dans la validation, comme nous le verrons bientôt.</p>
-
- <p>Enfin, notez que la relation est définie en utilisant <tt class="docutils literal"><span class="pre">models.ForeignKey</span></tt>. Ça
- dit à Django que chaque choix Choice est lié à un unique sondage Poll. Django
- supporte toutes les relations communes des bases de données: n vers 1, n vers m
- et 1 vers 1.</p>
-
- </div>
-
- <div class="section">
- <h1><a id="activation-des-mod-les" name="activation-des-mod-les">Activation des modèles</a></h1>
- <p>Ce petit bout de code de modèle donne à Django beaucoup d'informations. Avec
- lui, Django est capable de:</p>
- <blockquote>
- <ul class="simple">
- <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>)
- pour cette appli.</li>
- <li>Créer une API en Python d'accès à la base de données afin d'accéder aux
- objets Poll et Choice.</li>
- </ul>
- </blockquote>
-
- <p>Mais avant, nous avons besoin de dire à notre projet que l'application <tt class="docutils literal"><span class="pre">polls</span></tt>
- est installée.</p>
- <div class="admonition-philosophie admonition">
- <p class="first admonition-title">Philosophie</p>
- <p class="last">Les applis Django sont « pluggables » : Vous pouvez utiliser une appli dans
- de nombreux projets, et vous pouvez distribuer des applis, parce qu'elles ne
- doivent pas dépendre d'une installation Django donnée.</p>
- </div>
- <p>Éditez à nouveau le fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>, et changez l'option
- <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
- ressembler à ça:</p>
-
- <pre class="literal-block">
- INSTALLED_APPS = (
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.sites',
- 'monsite.polls'
- )
- </pre>
- <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
- autre commande:</p>
- <pre class="literal-block">
- python manage.py sql polls
- </pre>
- <p>Vous devriez voir ce qui suit (les instructions SQL CREATE TABLE pour l'appli
- polls):</p>
- <pre class="literal-block">
- BEGIN;
- CREATE TABLE "polls_poll" (
- "id" serial NOT NULL PRIMARY KEY,
- "question" varchar(200) NOT NULL,
- "pub_date" timestamp with time zone NOT NULL
- );
- CREATE TABLE "polls_choice" (
- "id" serial NOT NULL PRIMARY KEY,
- "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
- "choice" varchar(200) NOT NULL,
- "votes" integer NOT NULL
- );
- COMMIT;
-
- </pre>
- <p>Notez ceci:</p>
- <blockquote>
- <ul class="simple">
- <li>Le nom des tables est généré automatiquement en combinant le nom de
- 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
- <tt class="docutils literal"><span class="pre">choice</span></tt>. (Vous pouvez changer ce comportement.)</li>
- <li>Les clés primaires (IDs) sont ajoutées automatiquement. (Vous pouvez aussi
- le changer.)</li>
- <li>Par convention, Django ajoute <tt class="docutils literal"><span class="pre">"_id"</span></tt> à nom de champ de la clé
- étrangère. Oui, vous pouvez également le changer.</li>
-
- <li>La relation de la clé étrangère est faite explicitement par une clause
- <tt class="docutils literal"><span class="pre">REFERENCES</span></tt>.</li>
- <li>Le code est rédigé pour la base de données que vous employez, donc les
- types de champ spécifiques à chaque base de données, tel que
- <tt class="docutils literal"><span class="pre">auto_increment</span></tt> (MySQL), <tt class="docutils literal"><span class="pre">serial</span></tt> (PostgreSQL), ou
- <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.
- Même chose pour les quotes de noms de champs -- par exemple, l'utilisation
- de doubles ou simples quotes. L'auteur de ce tutoriel utilise PostgreSQL,
- donc les traces d'exécution de l'exemple sont dans la syntaxe PostgreSQL.</li>
-
- <li>La commande <cite>sql</cite> ne lance en fait pas le code SQL dans votre base de
- données - il l'affiche juste à l'écran pour que vous puissiez voir quel
- code SQL est requis d'après Django. Si vous aviez voulu, nous auriez pu
- copier et coller ce code SQL dans l'invite interactive de votre base de
- données. Cependant, comme nous le verrons d'ici peu, Django fournit une
- moyen plus simple d'éxecuter le SQL dans la base de données.</li>
- </ul>
- </blockquote>
- <dl class="docutils">
- <dt>Si vous êtes intéressé, lancez aussi les commandes suivantes :</dt>
- <dd><ul class="first last simple">
- <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
- dans la construction de vos modèles.</li>
-
- <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
- initiales requises pour le framework d'administration de Django et pour
- vos modèles.</li>
- <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>
-
- <span class="pre">TABLE</span></tt> nécessaires pour cette appli, selon les table qui existent déjà
- dans votre base de données (s'il y en a).</li>
- <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>
- <span class="pre">INDEX</span></tt> pour cette appli.</li>
-
- <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
- des commandes 'sql', 'sqlinitialdata', et 'sqlindexes'.</li>
- </ul>
- </dd>
- </dl>
- <p>L'examen de la trace d'exécution de ces commandes peut vous aider à
- comprendre ce qui se passe en fait en bas-niveau.</p>
- <p>À présent, lancez à nouveau <tt class="docutils literal"><span class="pre">syncdb</span></tt> pour créer ces tables du modèles dans
- votre base de données:</p>
-
- <pre class="literal-block">
- python manage.py syncdb
- </pre>
- <p>La commande <tt class="docutils literal"><span class="pre">syncdb</span></tt> exécute le code sql de 'sqlall' dans votre base de
- données pour toutes les applis de <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> qui n'existent pas encore
- dans votre base de données. Ça crée toutes les tables, initie les données et
- indexes pour toutes les applis que vous avez ajouté dans votre projet depuis la
- dernière fois que vous avez lancé syncdb. <tt class="docutils literal"><span class="pre">syncdb</span></tt> peut être appelé aussi
- souvent que vous le souhaitez, et ça ne créera que les tables qui n'existaient
- pas auparavant.</p>
- <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
- ce que l'outil <tt class="docutils literal"><span class="pre">manage.py</span></tt> peut faire.</p>
-
- </div>
-
- <div class="section">
- <h1><a id="jouons-avec-l-api" name="jouons-avec-l-api">Jouons avec l'API</a></h1>
- <p>Maintenant, jetons un œil au shell Python interactif et jouons avec l'API libre
- que Django nous fournit. Pour invoquer le shell Python, utilisez cette
- commande:</p>
- <pre class="literal-block">
- python manage.py shell
- </pre>
- <p>Nous utilisons celle-ci au lieu de simplement taper « python » parce que
- <tt class="docutils literal"><span class="pre">manage.py</span></tt> définit l'environnement du projet pour vous. « Définir
- l'environnement » signifie deux choses:</p>
- <blockquote>
- <ul>
- <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
- parties de Django se référent aux projets à l'aide de la notation Python
- de chemins séparés par des points (par exemple, <cite>'monsite.polls.models'`</cite>
-
- ). Et pour que ça marche, le paquetage <tt class="docutils literal"><span class="pre">monsite</span></tt> doit être dans
- <tt class="docutils literal"><span class="pre">sys.path</span></tt>.</p>
- <p>Nous avons déjà vu un exemple de cela : l'option <tt class="docutils literal"><span class="pre">INSTALLED_APPS</span></tt> est
- une liste de paquetages utilisant la notation de chemins séparés par des
- points.</p>
- </li>
- <li><p class="first">Définition de la variable d'environnement <tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE</span></tt>, qui
- indique à Django le chemin vers votre fichier <tt class="docutils literal"><span class="pre">settings.py</span></tt>.</p>
-
- </li>
- </ul>
- </blockquote>
- <div class="admonition-outrepasser-manage-py admonition">
- <p class="first admonition-title">Outrepasser manage.py</p>
- <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
- 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>
- <span class="pre">monsite</span></tt> fonctionne) et définissez la variable d'environnement
-
- <tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE</span></tt> à <tt class="docutils literal"><span class="pre">monsite.settings</span></tt>.</p>
- <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
- django-admin.py</a>.</p>
- </div>
-
- <p>Une fois que vous êtes dans le shell, explorez l'API pour la base de données:</p>
-
- <pre class="literal-block">
- # Importe les classes de modèle que nous venons d'écrire.
- >>> from monsite.polls.models import Poll, Choice
-
- # Aucun sondage n'est dans le système pour l'instant.
-
- >>> Poll.objects.all()
- []
-
- # Crée un nouveau sondage Poll.
- >>> from datetime import datetime
- >>> p = Poll(question="Quoi de neuf ?", pub_date=datetime.now())
-
- # Sauvegarde l'objet dans la base de données.
- # Vous devez appeler save() explicitement.
- >>> p.save()
-
- # Maintenant il a un ID. Notez que ça pourrait afficher "1L" au lieu de "1",
- # cela dépend de la base de données que vous utilisez. Ce n'est pas un bug ;
- # ça signifie juste que le backend de votre base de données préfère
- # retourner les entiers comme des objets de type entiers longs en Python.
- >>> p.id
- 1
-
- # Accède aux colonnes de base de données via les attributs Python.
-
- >>> p.question
- "Quoi de neuf ?"
- >>> p.pub_date
- datetime.datetime(2005, 7, 15, 12, 00, 53)
-
- # Change les valeurs en modifiant les attributs, puis en appelant save().
- >>> p.pub_date = datetime(2005, 4, 1, 0, 0)
- >>> p.save()
-
- # objects.all() affiche tous les sondages de la base de données.
- >>> Poll.objects.all()
- [<Poll: Poll object>]
- </pre>
-
- <p>Attendez une minute. <tt class="docutils literal"><span class="pre"><Poll:</span> <span class="pre">Poll</span> <span class="pre">object></span></tt> est, à vrai dire, une
- représentation qui n'apporte rien sur l'objet. Corrigeons cela en éditant le
- modèle des sondages (dans le fichier <tt class="docutils literal"><span class="pre">polls/models.py</span></tt>) et en ajoutant une
- 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>
-
- <pre class="literal-block">
- class Poll(models.Model):
- # ...
- def __str__(self):
- return self.question
-
- class Choice(models.Model):
- # ...
- def __str__(self):
- return self.choice
- </pre>
-
- <p>Il est important d'ajouter les méthodes <tt class="docutils literal"><span class="pre">__str__()</span></tt> dans vos modèles, pas
- seulement pour votre propre bien-être lorsque vous utilisez la console
- interactive, mais aussi parce que les représentations d'objets sont utilisées à
- travers l'interface d'administration auto-générée de Django.</p>
-
- <p>Notez que ce sont des méthodes standards de Python. Ajoutons une méthode perso,
- juste pour la démo:</p>
-
- <pre class="literal-block">
- import datetime
- # ...
- class Poll(models.Model):
- # ...
- def was_published_today(self):
- return self.pub_date.date() == datetime.date.today()
- </pre>
-
- <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
- Python <tt class="docutils literal"><span class="pre">datetime</span></tt>.</p>
-
- <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>
- <span class="pre">shell</span></tt>:</p>
-
- <pre class="literal-block">
- >>> from monsite.polls.models import Poll, Choice
-
- # Vérifie que notre nouvelle méthode __str__() fonctionne.
- >>> Poll.objects.all()
- [<Poll: Quoi de neuf ?>]
-
- # Django fournit une riche API de recherche dans la base de données qui est
- # entièrement gérée par des arguments mot-clés.
- >>> Poll.objects.filter(id=1)
- [<Poll: Quoi de neuf ?>]
-
- >>> Poll.objects.filter(question__startswith='Quoi')
- [<Poll: Quoi de neuf ?>]
-
- # Récupére le sondage dont l'année est 2005. Bien sûr, si vous suivez ce
- # tutoriel dans une autre année, remplacez par la valeur appropriée.
- >>> Poll.objects.get(pub_date__year=2005)
- <Poll: Quoi de neuf ?>
-
- >>> Poll.objects.get(id=2)
- Traceback (most recent call last):
- ...
- DoesNotExist: Poll matching query does not exist.
-
- # La recherche par clé primaire est le cas le plus courant, donc Django
- # fournit un raccourci pour les recherches exactes sur clé primaire.
- # Ce qui suit est identique à Poll.objects.get(id=1).
- >>> Poll.objects.get(pk=1)
- <Poll: Quoi de neuf ?>
-
- # Vérifie que notre méthode perso fonctionne.
-
- >>> p = Poll.objects.get(pk=1)
- >>> p.was_published_today()
- False
-
- # Donne une liste de choix Choice au sondage Poll. L'appel à create
- # construit un nouvel objet choice, fait l'instruction INSERT , ajoute le
- # choix dans l'ensemble des choix disponibles et retourne le nouvel objet
- # Choice.
- >>> p = Poll.objects.get(pk=1)
- >>> p.choice_set.create(choice='Pas grand chose', votes=0)
- <Choice: Pas grand chose>
- >>> p.choice_set.create(choice='Le ciel', votes=0)
- <Choice: Le ciel>
- >>> c = p.choice_set.create(choice='Toujours en train de coder', votes=0)
-
- # Les objets Choice ont une API d'accès aux objets Poll qui leur sont liés.
- >>> c.poll
-
- <Poll: Quoi de neuf ?>
-
- # Et vice-versa: les objets Poll ont accès aux objets Choice.
- >>> p.choice_set.all()
- [<Choice: Pas grand chose>, <Choice: Le ciel>, <Choice: Toujours en train de coder>]
- >>> p.choice_set.count()
- 3
-
- # L'API suit automatiquement les relations aussi loin que vous en avez
- # besoin. Utilisez les doubles underscores pour séparer les relations.
- # Ça fonctionne sur autant de niveaux de profonteur que vous voulez. Il n'y
- # a pas de limite. Trouve tous les choix Choice pour n'importe quel sondage
- # dont le pub_date est 2005.
- >>> Choice.objects.filter(poll__pub_date__year=2005)
- [<Choice: Pas grand chose>, <Choice: Le ciel>, <Choice: Toujours en train de coder>]
-
- # Supprimons un des choix. Utilisez delete() pour se faire.
-
- >>> c = p.choice_set.filter(choice__startswith='Toujours en train')
- >>> c.delete()
- </pre>
-
- <p>Pour les détails complets au sujet de l'API de la base de données, lisez notre
- <a class="reference" href="http://www.djangoproject.com/documentation/db_api/">référence de l'API de base de données</a>.</p>
-
- <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
- tutoriel</a> pour voir le fonctionnement de l'interface d'administration
- automatique de Django.</p>
-
- <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
- documentation de Django</a>.</p>
-
- <p>Cette traduction correspond à la révision 3589 (post 0.95).</p>
-
- </div>
- </div>
- </article>
- <footer>
- <h6 property="schema:datePublished">— 17/06/2006</h6>
- </footer>
- </section>
- <section>
- <div>
- <h3>Articles peut-être en rapport</h3>
- <ul>
- <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>
- <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>
- <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'un formulaire et vues génériques">Rédaction de votre première appli Django, partie 4 : Conception d'un formulaire et vues génériques</a></li>
- </ul>
- </div>
- </section>
- <section>
- <div id="comments">
- <h3>Commentaires</h3>
-
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Paolo</span> le <span class="comment-date" property="schema:commentTime">17/06/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Django's tutorial part one translated in French.. simply fantastic :-)<br />
- Great news, keep up the good work!</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David</span> le <span class="comment-date" property="schema:commentTime">20/06/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Très bon travail, j'attends la suite avec impatience ! ;-)</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Phil</span> le <span class="comment-date" property="schema:commentTime">19/07/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Petite faute de typo, on créé le projet monsite, mais dans les exemples, on utilise mysite</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">19/07/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Bien vu, corrigé :)</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Flipper</span> le <span class="comment-date" property="schema:commentTime">05/08/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Petite faute de frappe, dans le petit paragraphe "Projets contre applis" il y a d'écrit "un base d'enregistrement"</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">05/08/2006</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Ok, merci c'est corrigé !</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">ark</span> le <span class="comment-date" property="schema:commentTime">11/01/2007</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>joli travail, merci :)</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Bastien</span> le <span class="comment-date" property="schema:commentTime">16/01/2007</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <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 "python manage.py inspectdb > monapp/models.py" à 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 />
- <br />
- class AuthMessage(models.Model):<br />
- id = models.IntegerField(primary_key=True)<br />
- user = models.ForeignKey(AuthUser)<br />
- message = models.TextField()<br />
- class Meta:<br />
- db_table = 'auth_message'<br />
- <br />
- 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>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">16/01/2007</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <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 />
- <br />
- user = models.ForeignKey('AuthUser')</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">[JO-JOJO]</span> le <span class="comment-date" property="schema:commentTime">07/05/2007</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>Bonjour,<br />
- <br />
- Merci encore pour tous ces tuto vraiment bien expliqués !<br />
- <br />
- 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 />
- <br />
- voilà donc comment j'ai fait cela : <br />
- categorie = models.ForeignKey(CategoriePhoto)<br />
- ImageField(upload_to='photos/%(categorie)s') <br />
- <br />
- Mais ceci ne marche pas ... pourquoi ? ca me créer un dossier qui s'appele " categorie)s " !!! bizarrreeee !<br />
- <br />
- Merci d'avance<br />
- <br />
- Joakim<br />
- </p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">07/05/2007</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <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 />
- <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 />
- <br />
- Pour faire court, il faudrait mettre :<br />
- ImageField(upload_to='photos/%(categorie)s' % {'categorie': nom-de-ta-catégorie})<br />
- <br />
- Bon courage dans ton apprentissage de Django :-).</p>
- </div>
- </div>
- <div class="comment" typeof="schema:UserComments">
- <p class="comment-meta">
- <span class="comment-author" property="schema:creator">Poipoi</span> le <span class="comment-date" property="schema:commentTime">06/11/2008</span> :
- </p>
- <div class="comment-content" property="schema:commentText">
- <p>J'ai eu un soucis lors de l'activation du modele; il y a eu l'erreur suivante:</p>
-
- <p>"__init__() got an unexpected keyword argument 'maxlength' "</p>
-
- <p>J'ai du remplacer par "maxlength" par "max_length" et ça a marché.</p>
-
- <p>config: <br />django 1<br />debian etch<br />bdd mysql</p>
- </div>
- </div>
-
- </div>
- </section>
-
-
- <footer>
- <nav>
- <p>
- <small>
- Je réponds quasiment toujours aux <a href="mailto:david%40larlet.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>
- </small>
- </p>
- </nav>
- </footer>
-
- </div>
-
- <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
-
- <script data-no-instant>InstantClick.init()</script>
-
- </body>
- </html>
|