IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel pour apprendre à utiliser le framework web Django


précédentsommairesuivant

XVII. Django ORM (Querysets)

Dans ce chapitre, nous allons apprendre comment Django se connecte à la base de données et comment il y enregistre des choses. On respire un grand coup et on y va !

XVII-A. Qu'est-ce qu'un QuerySet ?

Un QuerySet est, par essence, une liste d'objets d'un modèle donné. C'est ce qui vous permet de lire, trier et organiser des données présentes dans une base de données.

Il est plus simple d'apprendre avec un exemple. Et si nous nous intéressions à celui-ci ?

XVII-B. Le shell Django

Ouvrez la console de votre ordinateur (et non celle de PythonAnywhere) et tapez la commande suivante :

 
Sélectionnez
(myvenv) ~/djangogirls$ python manage.py shell

Ceci devrait maintenant s'afficher dans votre console :

 
Sélectionnez
(InteractiveConsole)
>>>

Vous êtes maintenant dans la console interactive de Django. C'est comme celle de Python, mais avec toute la magie qu'apporte Django. Du coup, les commandes Python sont aussi utilisables dans cette console.

XVII-B-1. Lister tous les objets

Essayons tout d'abord d'afficher tous nos articles. Vous pouvez le faire à l'aide de cette commande :

 
Sélectionnez
1.
2.
3.
4.
>>> Post.objects.all()
Traceback (most recent call last):
      File "<console>", line 1, in <module>
NameError: name 'Post' is not defined

Ooops ! Voilà que ça nous renvoie une erreur qui nous dit qu'il n'existe pas de Post. En effet, nous avons oublié de commencer par un « import » !

 
Sélectionnez
>>> from blog.models import Post

Rien de compliqué : nous importons le modèle Post depuis notre blog.models. Essayons à nouveau la commande précédente :

 
Sélectionnez
>>> Post.objects.all()
<QuerySet [<Post: my post title>, <Post: another post title>]>

Cela nous permet d'obtenir une liste des articles que nous avons créés tout à l'heure ! Rappelez-vous : nous avions créé ces articles à l'aide de l'interface d'administration de Django. Cependant, nous aimerions maintenant créer de nouveaux articles à l'aide de Python : comment allons-nous nous y prendre ?

XVII-B-2. Créer des objets

Voici comment créer un nouvel objet Post dans la base de données :

 
Sélectionnez
>>> Post.objects.create(author=me, title='Sample title', text='Test')

Cependant, il nous manque un petit quelque chose : me. Nous avons besoin de lui passer une instance du modèle User en guise d'auteur (author). Comment faire ?

Tout d'abord, il nous faut importer le modèle User :

 
Sélectionnez
>>> from django.contrib.auth.models import User

Avons-nous des utilisateurs dans notre base de données ? Voyons voir :

 
Sélectionnez
>>> User.objects.all()
<QuerySet [<User: ola>]>

C'est le superutilisateur que nous avions créé tout à l'heure ! Essayons maintenant d'obtenir une instance de l'utilisateur :

 
Sélectionnez
me = User.objects.get(username='ola')

Comme vous pouvez le voir, nous obtenons (get) un utilisateur (User) avec comme nom d'utilisateur (username) 'ola'. Cool ! Bien sûr, vous pouvez utiliser votre nom si vous le souhaitez.

Nous allons enfin pouvoir créer notre article :

 
Sélectionnez
>>> Post.objects.create(author=me, title='Sample title', text='Test')

Youpi ! Et si on vérifiait quand même si ça a marché ?

 
Sélectionnez
>>> Post.objects.all()
<QuerySet [<Post: my post title>, <Post: another post title>, <Post: Sample title>]>

Et voilà : un post de plus dans la liste !

XVII-B-3. Ajouter plus de posts

Amusez-vous à ajouter d'autres articles pour vous entraîner un peu. Essayez d'ajouter deux ou trois articles en plus puis passez à la partie suivante.

XVII-B-4. Filtrer les objets

L'intérêt des QuerySets, c'est que l'on peut les filtrer. Disons que nous aimerions retrouver tous les articles écrits par l'utilisateur Ola. Pour cela, nous allons utiliser filter à la place de all dans Post.objects.all(). Les parenthèses vont nous servir à préciser quelles sont les conditions auxquelles un article de blog doit se conformer pour être retenu par notre QuerySet. Dans notre exemple, author est égal à me. La manière de le dire en Django c'est : author=me. Maintenant, votre bout de code doit ressembler à ceci :

 
Sélectionnez
>>> Post.objects.filter(author=me)
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]

Et si nous voulions chercher les posts qui contiennent uniquement le mot « titre » dans le champ title ?

 
Sélectionnez
>>> Post.objects.filter(title__contains='title')
[<Post: Sample title>, <Post: 4th title of post>]

Il y a deux tirets bas (_) entre title et contains. L'ORM de Django utilise cette syntaxe afin de séparer les noms de champ (« title ») et les opérations ou les filtres (« contains »). Si vous n'utilisez qu'un seul tiret bas, vous allez obtenir une erreur du type : « FieldError: Cannot resolve keyword title_contains ».

Comment obtenir une liste de tous les articles publiés ? Cela se fait facilement en filtrant tous les articles qui ont une date de publication, published_date, dans le passé :

 
Sélectionnez
>>> from django.utils import timezone
>>> Post.objects.filter(published_date__lte=timezone.now())

Malheureusement, l'article que nous avons créé dans la console Python n'est pas encore publié. Allons corriger ce problème ! Dans un premier temps, nous aimerions obtenir une instance de l'article que nous voulons publier :

 
Sélectionnez
>>> post = Post.objects.get(title="Sample title")

Ensuite, publions-le grâce à notre méthode publish !

 
Sélectionnez
>>> post.publish()

Maintenant, essayez d'obtenir à nouveau la liste des articles publiés. Pour cela, appuyez trois fois sur la flèche du haut et appuyez sur entrée :

 
Sélectionnez
>>> Post.objects.filter(published_date__lte=timezone.now())
[<Post: Sample title>]

XVII-B-5. Classer les objets

Les QuerySets permettent aussi de trier la liste des objets. Essayons de les trier par le champ created_date :

 
Sélectionnez
>>> Post.objects.order_by('created_date')
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]

On peut aussi inverser l'ordre de tri en ajoutant - au début :

 
Sélectionnez
>>> Post.objects.order_by('-created_date')
[<Post: 4th title of post>,  <Post: My 3rd post!>, <Post: Post number 2>, <Post: Sample title>]

XVII-B-6. Chainer les QuerySets

Vous pouvez aussi combiner les QuerySets en les chainant les unes aux autres :

 
Sélectionnez
>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')

C'est un outil très puissant qui va vous permettre d'écrire des requêtes complexes.

Génial ! Vous êtes maintenant prête à passer à l'étape suivante ! Pour fermer le shell, tapez ceci :

 
Sélectionnez
>>> exit()
$

précédentsommairesuivant

Licence Creative Commons
Le contenu de cet article est rédigé par Django Girls et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2018 Developpez.com.