Django : Utilisation de la base de données via l’ORM

La base de données est prête, on peut maintenant jouer avec, en ajoutant quelques données d’exemple. Explorons l’API de l’ORM livré dans Django via le shell dans un premier temps:

challenge python

Utilisation de l’API de la DB


python manage.py shell


>>> from polls.models import Question, Choice   # Il faut importer les modèles en question. Voyez ça comme les namespace si vous venez de PHP.

# Forcément, c'est vide.
>>> Question.objects.all()
[]

Vous remarquez sans doutes la propriété objects. Je n’aime pas trop me dire qu’à chaque fois que je vais devoir requêter, il va falloir entrer dans cette propriété. Il semble que ce soit le manager du modèle, pour interagir avec la base, et avoir accès à la liste de queryset.

Créons simplement une nouvelle question maintenant. La doc explique qu’il faut faire attention au fait que le support de la timezone est obligatoire par défaut. En gros, vous ne pouvez pas insérer directement un timestamp (même si il a une timezone constante à UTC) il faut insérer une date avec sa timezone. J’ai tenté plusieurs choses pour contourner, et je n’ai rien trouvé. Bon, ca se paramètre votre programme, mais ça m’a plus gêner qu’autre chose.

Pour y arriver, et utiliser la convention de Django par défaut, utiliser timezone.now() depuis django.utils :

>>> from django.utils import timezone
>>> q = Question(question_text="Bla bla?", pub_date=timezone.now())

# Et on enregistre
>>> q.save()

# Maintenant, on peut accéder à ses propriétés.
>>> q.id
1

Pour ce souci avec la gestion des dates, en discutant sur le channel IRC #python-fr, on m’a parlé du parseur python-dateutil qui a l’air très aidant pour la gestion des dates avec Python.

Maintenant, on va lister nos enregistrements dans la table question :

>>> Question.objects.all()
[<Question: Question object>]

Vu que ce Question object n’est pas très causant, il faut ajouter une méthode sur les modèles dont vous souhaitez avoir une représentation un peu plus clair comme ceci

def __str__(self):
        return self.question_text

Je vous renvoie à la doc pour comprendre à quoi sert cette méthode, mais ça ne me parait pas très important à ce stade.

Du coup ensuite, au lieu d’avoir :

>>> Question.objects.all()
[<Question: Question object>]

vous vous retrouvez avec :

>>> Question.objects.all()
[<Question: BlaBla>]

J’aurais balancé toutes les propriétés sous forme de hash,tableau ou autre mais ça viendra certainement après !

Définir la relation inverse

Alors c’est assez surprenant, mais pas du tout expliqué sur le tuto de base. On a vu dans un précédent article comment définir une relation avec Django mais la définition de la relation inverse n’y est pas.

Prenons toujours l’exemple de la Question et du Choice :

q = Question.objects.get(id=2)

#Pour accéder à la relation inverse (Choice) par défaut, il on ne le donne pas précisément dans le modèle, on peut faire ceci:
q.choice_set.all()

Le tuto n’en dit pas plus, et ce serait une convention par défaut si vous ne définissez pas directement la relation inverse dans le modèle : _set.all().

Mais comment on donne un nom à cette relation inverse alors ? Comme ceci, dans le fichier models.py :

question = models.ForeignKey(Question, on_delete=models.CASCADE)
#devient :
question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='choice')

On peut ensuite créer un choix :

>>> q.choice.all()
[]
>>> c = q.choice.create(choice_text='FooBar', votes=0)
>>> c.question
<Question: BlaBla>

Dans le prochain billet, et va s’attaquer à l’admin 🙂

metrogeek

Comments 1

Laisser un commentaire