- en
- Langue : fr
Écriture de votre première application Django, 1ère partie¶
Apprenons avec un exemple.
Tout au long de ce tutoriel, nous vous guiderons dans la création d’une application simple de sondage.
Cela consistera en deux parties :
Un site public qui permet à des gens de voir les sondages et d’y répondre.
Un site d’administration qui permet d’ajouter, de modifier et de supprimer des sondages.
Nous supposerons que Django est déjà installé. Vous pouvez savoir si Django est installé et sa version en exécutant la commande suivante :
$ python -c "import django; print(django.get_version())"
Si Django est installé, vous devriez voir apparaître la version de l’installation. Dans le cas contraire, vous obtiendrez une erreur disant « No module named django » (aucun module nommé django).
Ce didacticiel est écrit pour Django 1.8 et Python 3.2 (ou plus récent). Si la version de Django ne correspond pas, référez-vous au didacticiel correspondant à votre version de Django en utilisant le sélecteur de version au bas de cette page, ou mettez à jour Django à la version la plus récente. Si vous utilisez encore Python 2.7, il sera nécessaire d’ajuster légèrement les exemples de code, comme expliqué dans les commentaires.
Consultez Comment installer Django pour tout conseil sur la manière de supprimer d’anciennes versions de Django pour en installer une nouvelle.
Où obtenir de l’aide :
Si vous avez des problèmes au long de ce tutoriel, écrivez un message sur django-users (anglophone) ou passez sur #django-fr sur irc.freenode.net pour discuter avec d’autres utilisateurs de Django qui pourraient vous aider.
Création d’un projet¶
Si c’est la première fois que vous utilisez Django, vous devrez vous occuper de quelques éléments de configuration initiaux. Plus précisément, vous devrez lancer la génération automatique de code qui mettra en place un projet Django – un ensemble de réglages particuliers à une instance de Django, qui comprend la configuration de la base de données, des options spécifiques à Django et d’autres propres à l’application.
Depuis un terminal en ligne de commande, déplacez-vous à l’aide de la commande cd dans un répertoire dans lequel vous souhaitez conserver votre code, puis lancez la commande suivante :
$ django-admin startproject mysite
Cela va créer un répertoire mysite dans le répertoire courant. Si cela ne fonctionne pas, consultez Problèmes d’exécution de django-admin.
Note
Vous devez éviter de nommer vos projets en utilisant des noms réservés de Python ou des noms de composants de Django. Cela signifie en particulier que vous devez éviter d’utiliser des noms comme django (qui entrerait en conflit avec Django lui-même) ou test (qui entrerait en conflit avec un composant intégré de Python).
À quel endroit ce code devrait-il se trouver ?
Si vous avez une expérience en PHP, vous avez probablement l’habitude de placer votre code dans le répertoire racine de votre serveur Web (comme /var/www/). Avec Django, ne le faites pas. Ce n’est pas une bonne idée de mettre du code Python dans le répertoire racine de votre serveur Web, parce que cela crée le risque que l’on puisse voir votre code sur le Web, ce qui n’est pas bon pour la sécurité.
Mettez votre code dans un répertoire en dehors de la racine de votre serveur Web, comme par exemple home/moncode.
Voyons ce que startproject a créé :
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
Ces fichiers sont :
Le premier répertoire racine mysite/ n’est qu’un contenant pour votre projet. Son nom n’a pas d’importance pour Django ; vous pouvez le renommer comme vous voulez.
manage.py : un utilitaire en ligne de commande qui vous permet d’interagir avec ce projet Django de différentes façons. Vous trouverez toutes les informations nécessaires sur manage.py dans django-admin et manage.py.
Le sous-répertoire mysite/ correspond au paquet Python effectif de votre projet. C’est le nom du paquet Python que vous devrez utiliser pour importer ce qu’il contient (par ex. mysite.urls).
mysite/__init__.py : un fichier vide qui indique à Python que ce répertoire doit être considéré comme un paquet (lisez informations sur les paquets (en) dans la documentation officielle de Python si vous êtes débutant avec ce langage).
mysite/settings.py : réglages et configuration de ce projet Django. Les réglages de Django vous apprendra tout sur le fonctionnement des réglages.
mysite/urls.py : les déclarations des URL de ce projet Django, une sorte de « table des matières » de votre site Django. Vous pouvez en lire plus sur les URL dans Distribution des URL.
mysite/wsgi.py : un point d’entrée pour les serveurs Web compatibles WSGI pour déployer votre projet. Voir Comment déployer avec WSGI pour plus de détails.
Configuration de la base de données¶
Maintenant, ouvrez mysite/settings.py. C’est un module Python tout à fait normal, avec des variables de module qui représentent des réglages de Django.
La configuration par défaut utilise SQLite. Si vous débutez avec les bases de données ou que vous voulez juste essayer Django, il s’agit du choix le plus simple. SQLite est inclus dans Python, vous n’aurez donc rien d’autre à installer pour utiliser ce type de base de données. Lorsque vous démarrez votre premier projet réel, cependant, vous pouvez utiliser une base de données plus robuste comme PostgreSQL, afin d’éviter les maux de tête consécutifs au changement perpétuel d’une base de données à l’autre.
Si vous souhaitez utiliser une autre base de données, installez le connecteur de base de données approprié, et changez les clés suivantes dans l’élément 'default' de DATABASES pour indiquer les paramètres de connexion de votre base de données :
ENGINE – Choisissez parmi 'django.db.backends.sqlite3', 'django.db.backends.postgresql_psycopg2', 'django.db.backends.mysql' ou 'django.db.backends.oracle'. D’autres moteurs sont également disponibles.
NAME – Le nom de votre base de données. Si vous utilisez SQLite, la base de données sera un fichier sur votre ordinateur. Dans ce cas, NAME doit être le chemin absolu complet de celui-ci, y compris le nom de fichier. La valeur par défaut, os.path.join(BASE_DIR, 'db.sqlite3'), stocke ce fichier dans le répertoire de votre projet.
Si vous utilisez une autre base de données que SQLite, des réglages supplémentaires doivent être indiqués, comme USER, PASSWORD ou HOST. Pour plus de détails, consultez la documentation de référence de DATABASES.
Note
Si vous utilisez PostgreSQL ou MySQL, assurez-vous maintenant d’avoir créé la base de données. Faites-le avec CREATE DATABASE nom_de_la_base; dans le shell interactif de votre base de données.
Si vous utilisez SQLite, vous n’avez rien à créer à l’avance - le fichier de la base de données sera automatiquement créé lorsque ce sera nécessaire.
Puisque vous êtes en train d’éditer mysite/settings.py, définissez TIME_ZONE selon votre fuseau horaire.
Notez également le réglage INSTALLED_APPS au début du fichier. Cette variable contient le nom des applications Django qui sont actives dans cette instance de Django. Les applications peuvent être utilisées dans des projets différents, et vous pouvez empaqueter et distribuer les vôtres pour que d’autres les utilisent dans leurs projets.
Par défaut, INSTALLED_APPS contient les applications suivantes, qui sont toutes contenues dans Django :
django.contrib.admin – Le site d’administration. Vous l’utiliserez dans la deuxième partie de ce tutoriel.
django.contrib.auth – Un système d’authentification.
django.contrib.contenttypes – Une structure pour les types de contenu (content types).
django.contrib.sessions – Un cadre pour les sessions.
django.contrib.messages – Un cadre pour l’envoi de messages.
django.contrib.staticfiles – Une structure pour la prise en charge des fichiers statiques.
Ces applications sont incluses par défaut par commodité parce que ce sont les plus communément utilisées.
Certaines de ces applications utilisent toutefois au moins une table de la base de données, donc il nous faut créer les tables dans la base avant de pouvoir les utiliser. Pour ce faire, lancez la commande suivante :
$ python manage.py migrate
La commande migrate examine le réglage INSTALLED_APPS et crée les tables de base de données nécessaires en fonction des réglages de base de données dans votre fichier mysite/settings.py et des migrations de base de données contenues dans l’application (nous les aborderons plus tard). Vous verrez apparaître un message pour chaque migration appliquée. Si cela vous intéresse, lancez le client en ligne de commande de votre base de données et tapez \dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite) ou SELECT TABLE_NAME FROM USER_TABLES; (Oracle) pour afficher les tables créées par Django.
Pour les minimalistes
Comme il a été indiqué ci-dessus, les applications incluses par défaut sont les plus communes, mais tout le monde n’en a pas forcément besoin. Si vous n’avez pas besoin d’une d’entre elles (ou de toutes), vous êtes libre de commenter ou effacer les lignes concernées du règlage INSTALLED_APPS avant de lancer migrate. La commande migrate n’exécutera les migrations que pour les applications listées dans INSTALLED_APPS.
Le serveur de développement¶
Vérifions que votre projet Django fonctionne. Déplacez-vous dans le répertoire mysite si ce n’est pas déjà fait, et lancez les commandes suivantes :
$ python manage.py runserver
Vous verrez les messages suivants défiler en ligne de commande :
Performing system checks... 0 errors found January 13, 2016 - 15:50:53 Django version 1.8, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Vous avez démarré le serveur de développement de Django, un serveur Web léger entièrement écrit en Python. Nous l’avons inclus avec Django de façon à vous permettre de développer rapidement, sans avoir à vous occuper de la configuration d’un serveur de production – comme Apache – tant que vous n’en avez pas besoin.
C’est le moment de noter soigneusement ceci : n’utilisez jamais ce serveur pour quoi que ce soit qui s’approche d’un environnement de production. Il est fait seulement pour tester votre travail pendant le développement (notre métier est le développement d’environnements Web, pas de serveurs Web).
Maintenant que le serveur tourne, allez à l’adresse http://127.0.0.1:8000 avec votre navigateur Web. Vous verrez une page avec le message « Welcome to Django » sur un joli fond bleu pastel. Ça marche !
Modification du port
Par défaut, la commande runserver démarre le serveur de développement sur l’IP interne sur le port 8000.
Si vous voulez changer cette valeur, passez-la comme paramètre sur la ligne de commande. Par exemple, cette commande démarre le serveur sur le port 8080 :
$ python manage.py runserver 8080
Si vous voulez changer l’IP du serveur, passez-la comme paramètre avec le port. Pour écouter toutes les IP publiques (utile si vous souhaitez montrer votre travail à des personnes sur d’autres ordinateurs de votre réseau), faites :
$ python manage.py runserver 0.0.0.0:8000
La documentation complète du serveur de développement se trouve dans la référence de runserver.
Rechargement automatique de runserver
Le serveur de développement recharge automatiquement le code Python lors de chaque requête si nécessaire. Vous ne devez pas redémarrer le serveur pour que les changements de code soient pris en compte. Cependant, certaines actions comme l’ajout de fichiers ne provoquent pas de redémarrage, il est donc nécessaire de redémarrer manuellement le serveur dans ces cas.
Création des modèles¶
Maintenant que votre environnement – un « projet » – est en place, vous êtes prêt à commencer à travailler.
Chaque application que vous écrivez avec Django est en fait un paquet Python qui respecte certaines conventions. Django est livré avec un utilitaire qui génère automatiquement la structure des répertoires de base d’une application, ce qui vous permet de vous concentrer sur l’écriture du code, plutôt que sur la création de répertoires.
Projets vs. applications
Quelle est la différence entre un projet et une application ? Une application est une application Web qui fait quelque chose – par exemple un système de blog, une base de données publique ou une application de sondage. Un projet est un ensemble de réglages et d’applications pour un site Web particulier. Un projet peut contenir plusieurs applications. Une application peut apparaître dans plusieurs projets.
Vos applications peuvent se trouver à n’importe quel endroit de votre chemin de recherche Python. Dans ce didacticiel, nous allons créer une application de sondage au même niveau que le fichier manage.py pour qu’elle puisse être importée comme module de premier niveau plutôt que comme sous-module de monsite.
Pour créer votre application, assurez-vous d’être dans le même répertoire que manage.py et saisissez cette commande :
$ python manage.py startapp polls
Cela va créer un répertoire polls, qui est structuré de la façon suivante :
polls/
__init__.py
admin.py
migrations/
__init__.py
models.py
tests.py
views.py
Cette structure de répertoire accueillera l’application de sondage.
La première étape dans l’écriture d’une application Web utilisant une base de données dans Django est la définition de vos modèles – essentiellement, votre schéma de base de données, avec quelques métadonnées supplémentaires.
Philosophie
Un modèle est la source d’information unique et définitive pour vos données. Il contient les champs essentiels et le comportement attendu des données que vous stockerez. Django respecte la philosophie DRY (Don’t Repeat Yourself, « ne vous répétez pas »). Le but est de définir le modèle des données à un seul endroit, et ensuite de dériver automatiquement ce qui est nécessaire à partir de celui-ci.
Ceci inclut les migrations. Au contraire de Ruby On Rails, par exemple, les migrations sont entièrement dérivées du fichier des modèles et ne sont fondamentalement qu’un historique que Django peut parcourir pour mettre à jour le schéma de la base de données pour qu’il corresponde aux modèles actuels.
Dans notre application de sondage simple, nous allons créer deux modèles : Question et Choice (choix). Une Question possède une question et une date de mise en ligne. Un choix a deux champs : le texte représentant le choix et le décompte des votes. Chaque choix est associé à une Question.
Ces concepts sont représentés par de simples classes Python. Éditez le fichier polls/models.py de façon à ce qu’il ressemble à ceci :
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
Le code est trivial. Chaque modèle est représenté par une classe qui hérite de django.db.models.Model. Chaque modèle possède des variables de classe, chacune d’entre elles représentant un champ de la base de données pour ce modèle.
Chaque champ est représenté par une instance d’une classe Field – par exemple, CharField pour les champs de type caractère, et DateTimeField pour les champs date et heure. Cela indique à Django le type de données que contient chaque champ.
Le nom de chaque instance de Field (par exemple, question_text ou pub_date) est le nom du champ en interne. Vous l’utiliserez dans votre code Python et votre base de données l’utilisera comme nom de colonne.
Vous pouvez utiliser le premier paramètre de position (facultatif) d’un Field pour donner un nom plus lisible au champ. C’est utilisé par le système d’introspection de Django, et aussi pour la documentation. Si ce paramètre est absent, Django utilisera le nom du champ interne. Dans l’exemple, nous n’avons défini qu’un seul nom plus lisible, pour Question.pub_date. Pour tous les autres champs, nous avons considéré que le nom interne était suffisamment lisible.
Certaines classes Field possèdent des paramètres obligatoires. La classe CharField, par exemple, a besoin d’un attribut max_length. Ce n’est pas seulement utilisé dans le schéma de base de la base de données, mais également pour valider les champs, comme nous allons voir prochainement.
Un champ Field peut aussi autoriser des paramètres facultatifs ; dans notre cas, nous avons défini à 0 la valeur default de votes.
Finalement, notez que nous définissons une relation, en utilisant ForeignKey. Cela indique à Django que chaque vote (Choice) n’est relié qu’à une seule Question. Django propose tous les modèles classiques de relations : plusieurs-à-un, plusieurs-à-plusieurs, un-à-un.
Activation des modèles¶
Ce petit morceau de code décrivant les modèles fournit beaucoup d’informations à Django. Cela lui permet de :
Créer un schéma de base de données (instructions CREATE TABLE) pour cette application.
Créer une API Python d’accès aux bases de données pour accéder aux objets Question et Choice.
Mais il faut d’abord indiquer à notre projet que l’application de sondages polls est installée.
Philosophie
Les applications de Django sont comme des pièces d’un jeu de construction : vous pouvez utiliser une application dans plusieurs projets, et vous pouvez distribuer les applications, parce qu’elles n’ont pas besoin d’être liées à une installation Django particulière.
Éditez encore une fois le fichier mysite/settings.py et modifiez le réglage INSTALLED_APPS pour qu’il contienne la chaîne de caractères 'polls'. Il devrait donc ressembler à ceci :
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
)
Maintenant, Django sait qu’il doit inclure l’application polls. Exécutons une autre commande :
$ python manage.py makemigrations polls
Vous devriez voir quelque chose de similaire à ceci :
Migrations for 'polls':
0001_initial.py:
- Create model Question
- Create model Choice
- Add field question to choice
En exécutant makemigrations, vous indiquez à Django que vous avez effectué des changements à vos modèles (dans ce cas, vous en avez créé) et que vous aimeriez que ces changements soient stockés sous forme de migration.
Les migrations sont le moyen utilisé par Django pour stocker les modifications de vos modèles (et donc de votre schéma de base de données), ce ne sont que des fichiers sur le disque. Vous pouvez consultez la migration pour vos nouveaux modèles si vous le voulez ; il s’agit du fichier polls/migrations/0001_initial.py. Soyez sans crainte, vous n’êtes pas censé les lire chaque fois que Django en crée, mais ils sont conçus pour être humainement lisibles au cas où vous auriez besoin d’adapter manuellement les processus de modification de Django.
Il existe une commande qui exécute les migrations et gère automatiquement votre schéma de base de données, elle s’appelle migrate. Nous y viendrons bientôt, mais tout d’abord, voyons les instructions SQL que la migration produit. La commande sqlmigrate accepte des noms de migrations et affiche le code SQL correspondant :
$ python manage.py sqlmigrate polls 0001
Vous devriez voir quelque chose de similaire à ceci (remis en forme par souci de lisibilité) :
BEGIN;
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
COMMIT;
Notez les points suivants :
Ce que vous verrez dépendra de la base de données que vous utilisez. L’exemple ci-dessus est généré pour PostgreSQL.
Les noms de tables sont générés automatiquement en combinant le nom de l’application (polls) et le nom du modèle en minuscules – question et choice (vous pouvez modifier ce comportement).
Des clés primaires (ID) sont ajoutées automatiquement (vous pouvez modifier ceci également).
Par convention, Django ajoute "_id" au nom de champ de la clé étrangère. Et oui, vous pouvez aussi changer ça.
La relation de clé étrangère est rendue explicite par une contrainte FOREIGN KEY. Ne prenez pas garde aux parties DEFERRABLE; elles ne font qu’indiquer à PostgreSQL de ne pas contrôler la clé étrangère avant la fin de la transaction.
Ce que vous voyez est adapté à la base de données que vous utilisez. Ainsi, des champs spécifiques à celle-ci comme auto_increment (MySQL), serial (PostgreSQL) ou integer primary key autoincrement (SQLite) sont gérés pour vous automatiquement. Tout comme pour les guillemets autour des noms de champs (simples ou doubles).
La commande sqlmigrate n’exécute pas réellement la migration dans votre base de données - elle se contente de l’afficher à l’écran de façon à vous permettre de voir le code SQL que Django pense nécessaire. C’est utile pour savoir ce que Django s’apprête à faire ou si vous avez des administrateurs de base de données qui exigent des scripts SQL pour faire les modifications.
Si cela vous intéresse, vous pouvez aussi exécuter python manage.py check; cette commande vérifie la conformité de votre projet sans appliquer de migration et sans toucher à la base de données.
Maintenant, exécutez à nouveau la commande migrate pour créer les tables des modèles dans votre base de données :
$ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: admin, contenttypes, polls, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying <migration name>... OK
La commande migrate sélectionne toutes les migrations qui n’ont pas été appliquées (Django garde la trace des migrations appliquées en utilisant une table spéciale dans la base de données : django_migrations) puis les exécute dans la base de données, ce qui consiste essentiellement à synchroniser les changements des modèles avec le schéma de la base de données.
Les migrations sont très puissantes et permettent de gérer les changements de modèles dans le temps, au cours du développement d’un projet, sans devoir supprimer la base de données ou ses tables et en refaire de nouvelles. Une migration s’attache à mettre à jour la base de données en live, sans perte de données. Nous les aborderons plus en détails dans une partie ultérieure de ce didacticiel, mais pour l’instant, retenez le guide en trois étapes pour effectuer des modifications aux modèles :
Modifiez les modèles (dans models.py).
Exécutez python manage.py makemigrations pour créer des migrations correspondant à ces changements.
Exécutez python manage.py migrate pour appliquer ces modifications à la base de données.
La raison de séparer les commandes pour créer et appliquer les migrations est que celles-ci vont être ajoutées dans votre système de gestion de versions et qu’elles seront livrées avec l’application ; elles ne font pas que faciliter le développement, elles sont également exploitables par d’autres développeurs ou en production.
Lisez la documentation de django-admin pour avoir toutes les informations sur ce que manage.py peut faire.
Jouer avec l’interface de programmation (API)¶
Maintenant, utilisons un shell interactif Python pour jouer avec l’API que Django met gratuitement à votre disposition. Pour lancer un shell Python, utilisez cette commande :
$ python manage.py shell
Nous utilisons celle-ci au lieu de simplement taper « python », parce que manage.py définit la variable d’environnement DJANGO_SETTINGS_MODULE, qui indique à Django le chemin d’importation Python vers votre fichier mysite/settings.py.
Se passer de manage.py
Si vous préférez ne pas utiliser manage.py, pas de problème. Il suffit de définir la variable d’environnement DJANGO_SETTINGS_MODULE à mysite.settings, de lancer un shell Python standard et de configurer Django :
>>> import django
>>> django.setup()
Si une exception AttributeError apparaît, il est alors probable que vous utilisez une version de Django qui ne correspond pas à la version de ce tutoriel. Consultez alors une version plus ancienne de ce tutoriel ou installez une version plus récente de Django.
Vous devez exécuter python dans le même répertoire que celui où se trouve manage.py, ou assurez-vous que ce répertoire est dans le chemin Python afin que import mysite fonctionne.
Pour plus d’informations sur tout ceci, voyez la documentation de django-admin.
Une fois dans le shell, explorez l’API de base de données:
>>> from polls.models import Question, Choice # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
[]
# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> q.save()
# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> q.id
1
# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() displays all the questions in the database.
>>> Question.objects.all()
[<Question: Question object>]
Une seconde. <Question: Question object> n’est, à l’évidence, pas une représentation de cet objet très utile. On va arranger cela en éditant le modèle Question (dans le fichier polls/models.py) et en ajoutant une méthode __str__() à Question et à Choice:
from django.db import models
class Question(models.Model):
# ...
def __str__(self): # __unicode__ on Python 2
return self.question_text
class Choice(models.Model):
# ...
def __str__(self): # __unicode__ on Python 2
return self.choice_text
Il est important d’ajouter des méthodes __str__() à vos modèles, non seulement parce que c’est plus pratique lorsque vous utilisez le shell interactif, mais aussi parce que la représentation des objets est très utilisée dans l’interface d’administration automatique de Django.
__str__ ou __unicode__ ?
Avec Python 3, c’est simple, utilisez __str__().
Avec Python 2, il faut par contre définir des méthodes __unicode__() renvoyant du contenu unicode. Les modèles Django ont une méthode __str__() par défaut, qui appelle __unicode__() et convertit le résultat en chaîne d’octets UTF-8. Cela signifie que unicode(p) renverra une chaîne Unicode, et str(p) renverra une chaîne d’octets, avec les caractères codés en UTF-8. Python fait l’inverse : object possède une méthode __unicode__ qui appelle __str__ et interprète le résultat comme une chaîne d’octets ASCII. Cette différence peut prêter à confusion.
Si tout ceci ressemble à du chinois pour vous, utilisez simplement Python 3.
Notez que ce sont des méthodes Python classiques. Ajoutons une méthode personnalisée, juste pour la démonstration :
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
Notez l’ajout de import datetime et de from django.utils import timezone, pour référencer respectivement le module datetime standard de Python et les utilitaires de Django liés aux fuseaux horaires de django.utils.timezone. Si vous n’êtes pas habitué à la gestion des fuseaux horaires avec Python, vous pouvez en apprendre plus en consultant la documentation sur les fuseaux horaires.
Enregistrez ces modifications et retournons au shell interactif de Python en exécutant à nouveau python manage.py shell:
>>> from polls.models import Question, Choice
# Make sure our __str__() addition worked.
>>> Question.objects.all()
[<Question: What's up?>]
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
[<Question: What's up?>]
>>> Question.objects.filter(question_text__startswith='What')
[<Question: What's up?>]
# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>
# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
[]
# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> q.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
Pour plus d’informations sur les relations entre modèles, consultez Accès aux objets liés. Pour en savoir plus sur la manière d’utiliser les doubles soulignements pour explorer les champs par l’API, consultez Recherches par champs. Pour tous les détails sur l’API de base de données, consultez la référence de l’API de base de données.
Lorsque vous serez familiarisé avec l’API, lisez la partie 2 de ce tutoriel pour faire fonctionner l’interface d’administration automatique de Django.