Vous pouvez bien sûr conserver la structure de base qui est d'avoir un ensemble de créatures et/ou de personnages, et un ensemble de lieux avec des fonctions différentes (par exemple, pour un centre d'entrainement : terrain de foot, cantine, salle de muscu, dortoir). Il peut y avoir des variantes : Pour une maison des poupées il peut y avoir plusieurs chambres, une pièce commune, un jardin et une terrasse. Laissez libre cours à votre imagination.
Vous pouvez bien sûr conserver la structure de base qui est d'avoir un ensemble de créatures et/ou de personnages, et un ensemble de lieux avec des fonctions différentes (par exemple, pour un centre d'entrainement : terrain de foot, cantine, salle de muscu, dortoir). Il peut y avoir des variantes : Pour une maison des poupées il peut y avoir plusieurs chambres, une pièce commune, un jardin et une terrasse. Laissez libre cours à votre imagination.
-
Les créatures passent par différents états au cours de la journée en fonction des lieux qu'ils visitent.
+
Les personnages passent par différents états au cours de la journée en fonction des lieux qu'ils visitent.
<note tip> ** Rappel **
<note tip> ** Rappel **
-
Reprenez cette structure de données de type ''Animal'' -- ''Equipement'' utilisée dans les TD précédents
+
Reprenez cette structure de données de type ''Personnage'' -- ''Equipement'' utilisée dans les TD précédents
lieu = models.ForeignKey(Equipement, on_delete=models.CASCADE)
lieu = models.ForeignKey(Equipement, on_delete=models.CASCADE)
def __str__(self):
def __str__(self):
-
return self.id_char
+
return self.id_character
</code>
</code>
Vous deviez obtenir une interface simple de ce type:
Vous deviez obtenir une interface simple de ce type:
+
{{ :public:appro-s7:simple-hamster.png?600 |}}
{{ :public:appro-s7:simple-hamster.png?600 |}}
Ligne 71:
Ligne 71:
Vous pouvez exploiter les photos qui sont définies dans les attributs du modèle pour obtenir par exemple:
Vous pouvez exploiter les photos qui sont définies dans les attributs du modèle pour obtenir par exemple:
-
{{ :public:appro-s7:screenshot.png?500 |}}
+
{{ :public:appro-s7:animalerie_web.png?800 |}}
==== Formulaires Django ====
==== Formulaires Django ====
Ligne 170:
Ligne 170:
- Enfin, nous devons ajouter ''{% csrf_token %}'' juste après ''<form ...>''. C'est très important car c'est ce qui va permettre de sécuriser votre formulaire ! Si vous oubliez ce détail, Django se plaindra lorsque vous essaierez de sauvegarder le formulaire:
- Enfin, nous devons ajouter ''{% csrf_token %}'' juste après ''<form ...>''. C'est très important car c'est ce qui va permettre de sécuriser votre formulaire ! Si vous oubliez ce détail, Django se plaindra lorsque vous essaierez de sauvegarder le formulaire:
-
{{images/csrf2.png|alt=CSFR Forbidden page}}
Ok, voyons maintenant à quoi devrait ressembler le HTML contenu dans le fichier ''character_detail.html'' :
Ok, voyons maintenant à quoi devrait ressembler le HTML contenu dans le fichier ''character_detail.html'' :
Ligne 197:
Ligne 196:
Mais attendez une minute! Lorsque vous sélectionnez une option, que se passera-t-il?
Mais attendez une minute! Lorsque vous sélectionnez une option, que se passera-t-il?
Rien!
Rien!
-
Retournons à notre /vue//.
+
Retournons à notre //vue//.
==== Sauvegarder le contenu du formulaire ====
==== Sauvegarder le contenu du formulaire ====
-
<html>
+
-
<p>Ouvrez à nouveau <code>blog/views.py</code> dans l'éditeur de code. Actuellement, <code>post_new</code> n'est composé que des lignes de code suivantes :</p>
+
Ouvrez à nouveau ''blog/views.py'' dans l'éditeur de code. Actuellement, ''post_new'' n'est composé que des lignes de code suivantes :
-
</html>
+
<code python>
<code python>
def character_detail(request, id_character):
def character_detail(request, id_character):
Ligne 213:
Ligne 212:
</code>
</code>
-
<html>
+
-
<p>Lorsque nous envoyons notre formulaire, nous revenons à la même vue. Cependant, nous récupérons les données dans <code>request</code>, et plus particulièrement dans <code>request.POST</code>. Vous rappelez-vous comment dans le fichier HTML, notre définition de la variable <code><form></code> avait la méthode <code>method="POST"</code>? Tous les champs du formulaire se trouvent maintenant dans <code>request.POST</code>. Veillez à ne pas renommer <code>POST</code> en quoi que ce soit d'autre : la seule autre valeur autorisée pour <code>method</code> est <code>GET</code>. Malheureusement, nous n'avons pas le temps de rentrer dans les détails aujourd'hui.</p>
+
Lorsque nous envoyons notre formulaire, nous revenons à la même vue. Cependant, nous récupérons les données dans ''request'', et plus particulièrement dans ''request.POST''. Vous rappelez-vous comment dans le fichier HTML, notre définition de la variable ''form'' avait la méthode ''method=POST''? Tous les champs du formulaire se trouvent maintenant dans ''request.POST''. Veillez à ne pas renommer ''POST'' en quoi que ce soit d'autre : la seule autre valeur autorisée pour ''method'' est ''GET''. Malheureusement, nous n'avons pas le temps de rentrer dans les détails aujourd'hui.
-
<p>Donc dans notre <em>vue</em> nous avons deux situations différentes à gérer : la première quand on accède à la page pour la première fois et nous voulons un formulaire vide, et la seconde quand on revient à la <em>vue</em> avec les données que l'on a saisies dans le formulaire. Pour gérer ces deux cas, nous allons utiliser une condition
+
-
</html>
+
Donc dans notre //vue// nous avons deux situations différentes à gérer : la première quand on accède à la page pour la première fois et nous voulons un formulaire vide, et la seconde quand on revient à la //vue// avec les données que l'on a saisies dans le formulaire. Pour gérer ces deux cas, nous allons utiliser une condition
<code python>
<code python>
Ligne 225:
Ligne 225:
</code>
</code>
-
<html>
+
-
<p>Il faut maintenant remplir à l'endroit des pointillés <code>[...]</code>. Si <code>method</code> contient <code>POST</code> alors on veut construire le <code>MoveForm</code> avec les données du formulaire, n'est-ce pas ? Nous allons le faire comme cela :
+
Il faut maintenant remplir à l'endroit des pointillés ''[...]''. Si ''method'' contient ''POST'' alors on veut construire le ''MoveForm'' avec les données du formulaire, n'est-ce pas ? Nous allons le faire comme cela :
</html>
</html>
<code python>
<code python>
form = MoveForm(request.POST, instance=character)
form = MoveForm(request.POST, instance=character)
</code>
</code>
-
<html>
+
-
<p>La prochaine étape est de vérifier que le formulaire a été rempli correctement (tous les champs obligatoires ont été remplis et aucune valeur incorrecte n'a été envoyée). Nous allons faire ça en utilisant <code>form.is_valid()</code>.</p>
+
La prochaine étape est de vérifier que le formulaire a été rempli correctement (tous les champs obligatoires ont été remplis et aucune valeur incorrecte n'a été envoyée). Nous allons faire ça en utilisant ''form.is_valid()''.
-
<p>Testons donc si notre formulaire est valide et, si c'est le cas, sauvegardons-le !</p>
+
-
</html>
+
Testons donc si notre formulaire est valide et, si c'est le cas, sauvegardons-le !
<code python>
<code python>
if form.is_valid():
if form.is_valid():
Ligne 246:
Ligne 247:
</code>
</code>
-
<html>
-
<p>En gros, nous effectuons deux choses ici : nous sauvegardons le nouvel état du personnage grâce à <code>form.save</code> et nous mettons à jour l'occupation des lieux. Rappelez vous, tout déplacement du personnage s'acccompagne d'un changement d'occupation. Nous devons également modifier les lieux. <code>ancien_lieu.save()</code> et <code>nouveau_lieu.save()</code> sauvegarderont les changements. Et voilà, la mise à jour est enregistrée !</p>
-
<p>Enfin, ce serait génial si nous pouvions tout de suite aller à la page <code>character_detail</code> avec le contenu que nous venons de créer. Pour cela, nous avons besoin d'importer une dernière chose :
-
<p>Maintenant, nous allons ajouter la ligne qui signifie "aller à la page <code>character_detail</code> pour le changement qui vient d'être enregistré</p>
+
En gros, nous effectuons deux choses ici : nous sauvegardons le nouvel état du personnage grâce à ''form.save'' et nous mettons à jour l'occupation des lieux. Rappelez vous, tout déplacement du personnage s'acccompagne d'un changement d'occupation. Nous devons également modifier les lieux. ''ancien_lieu.save()'' et ''nouveau_lieu.save()'' sauvegarderont les changements. Et voilà, la mise à jour est enregistrée !
-
</html>
+
+
Enfin, ce serait génial si nous pouvions tout de suite aller à la page ''character_detail'' avec le contenu que nous venons de créer. Pour cela, nous avons besoin d'importer une dernière chose :
+
+
Maintenant, nous allons ajouter la ligne qui signifie "aller à la page ''character_detail'' pour le changement qui vient d'être enregistré.
<p>Voyons si ça marche. Allez à l'adresse <a href="http://127.0.0.1:8000/character/Tic/" target="_blank">http://127.0.0.1:8000/character/Tic/</a>, selectionnez un nouveau lieu, sauvegardez ... et voilà ! La mise a jour est prise en compte !</p>
+
Voyons si ça marche. Allez à l'adresse ''http://127.0.0.1:8000/character/Tic/'', selectionnez un nouveau lieu, sauvegardez ... et voilà ! La mise a jour est prise en compte !
-
</html>
+
==== Modèle complet ====
==== Modèle complet ====
Ligne 309:
Ligne 311:
</code>
</code>
-
==== Encore un petit effort : déployons ! ====
-
<html>
-
<p>Nos modifications fonctionnent-elles sur PythonAnywhere ? Pour le savoir, déployons à nouveau !</p>
-
<ul>
-
<li>Tout d'abord, commitez votre nouveau code et pushez le à nouveau sur GitHub:</li>
$ git commit -m "Added views to create/edit blog post inside the site."
-
$ git pus
-
</code></pre><ul>
-
<li>Puis, dans la console bash de <a href="https://www.pythonanywhere.com/consoles/" target="_blank">PythonAnywhere</a>:</li>
-
</ul>
-
<p></p><p class="code-label">Ligne de commande PythonAnywhere</p><p></p>
-
<pre><code>$ cd ~/<your-pythonanywhere-domain>.pythonanywhere.com
-
$ git pull
-
[...]
-
</code></pre><p>(N’oubliez pas de remplacer <code><your-pythonanywhere-domain></code> avec votre propre sous-domaine PythonAnywhere, sans les chevrons.)</p>
-
<ul>
-
<li>Enfin, allez sur <a href="https://www.pythonanywhere.com/web_app_setup/" target="_blank">"Web" page</a> (utilisez le bouton de menu en haut à droite de la console) et cliquez <strong>Reload</strong>. Actualisez votre blog <a href="https://subdomain.pythonanywhere.com" target="_blank">https://subdomain.pythonanywhere.com</a> pour voir les changements.</li>
-
</ul>
-
<p>Et normalement c'est tout ! Félicitations ! :)</p>