Projet / SemaineTech / 2013 / Ateliers / DjangoFrontend / Archive

ARCHIVE ATELIER Django Frontend

(12:01:56) davin.baragiotta: ----------------------------------------- DEBUT Atelier Django Frontend -----------------------------------------------
(12:02:00) davin.baragiotta: Bonjour à tous
(12:02:17) davin.baragiotta: aujourd'hui, je vous propose de continuer notre découverte de Django
(12:02:39) davin.baragiotta: le framework de développement web qu'on utilise à l'AUF
(12:02:48) davin.baragiotta: le contenu de présentation est ici :
(12:02:57) davin.baragiotta: https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support
(12:03:32) davin.baragiotta: cet atelier est la suite de l'atelier Django Backend... mais
(12:03:50) davin.baragiotta: mais il est possible de reprendre à partir de zéro
(12:04:03) davin.baragiotta: on aura beaucoup de fenêtres ouvertes
(12:04:22) davin.baragiotta: je vous recommande de bien organiser celles-ci et d'utiliser les onglets au maximum
(12:04:32) davin.baragiotta: * jabber : onglets tech et formation
(12:05:00) davin.baragiotta: * navigateur web : onglet présentation et code live.... soit ces 2 URLs
(12:05:03) davin.baragiotta: https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support
(12:05:11) davin.baragiotta: https://coderpad.io/771405
(12:06:40) davin.baragiotta: * un terminal : onglets...
** un pour faire rouler le serveur
** un autre pour les commandes Django (syncdb, startapp, etc.)
** autant d'onglets que de fichier en cours d'édition
(12:07:00) davin.baragiotta: moi j'édite mes fichiers en mode graphique... donc j'ai ces fenêtres en plus :
(12:07:16) davin.baragiotta: * nautilus : pour voir l'arborescence de mes fichiers
(12:07:41) davin.baragiotta: * gedit : avec autant d'onglets que j'ai de fichiers en cours d'édition
(12:08:02) davin.baragiotta: en général, en plus... j'organise mes onglets avec le flot de l'information dans Django
(12:08:22) davin.baragiotta: models | urls | views | template HTML |
(12:08:29) davin.baragiotta: voilà....
(12:08:45) davin.baragiotta: suivons le plan : https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support
(12:08:56) davin.baragiotta: INTRODUCTION
(12:09:13) davin.baragiotta: notre objectif d'hier

(12:09:28) davin.baragiotta: était de mettre en place le projet, comprendre l'architecture du projet...
(12:09:41) davin.baragiotta: ... et gérer nos modèles dans l'admin
(12:09:43) davin.baragiotta: notre objectif aujourd'hui...
(12:10:00) davin.baragiotta: ... c'est de présenter les infos dans des interfaces publiques
(12:10:12) davin.baragiotta: il nous faut donc d'abord des infos
(12:10:37) davin.baragiotta: on va reprendre à partir de ce qu'on avait fait hier
(12:10:40) davin.baragiotta: PARTIE 1 : RAPPELS ET AMORCE DU PROJET
(12:11:00) davin.baragiotta: Rappel : on fait du développement web
(12:11:02) davin.baragiotta: http://montrealpython.org/r/attachments/13/web-development.jpg
(12:11:47) davin.baragiotta: donc on code côté serveur en Python (avec Django pour nous faciliter la vie) pour répondre à une requête HTTP avec une réponse HTTP qui transmet du HTML comme contenu
(12:11:54) davin.baragiotta: faut comprendre ça, c'est la base...
(12:12:22) davin.baragiotta: aussi, dans notre contexte... notre projet est un projet de cartographie des établissements membres
(12:12:39) davin.baragiotta: on connaître les membres et leurs contacts
(12:12:42) davin.baragiotta: *veut
(12:12:59) davin.baragiotta: ok, je pars du principe que vous avez suivi l'atelier d'hier
(12:13:05) davin.baragiotta: sur la page de présentation
(12:13:12) davin.baragiotta: sous "Amorce du projet"
(12:13:31) davin.baragiotta: on présente plusieurs options pour reprendre le fil
(12:13:59) davin.baragiotta: 1. partir des sources : ne pas le faire... malheureusement, ce ne sont que des sources pour Django 1.1.1 (ça vient du ancien atelier)
(12:14:17) davin.baragiotta: 2. repartir de votre d'hier : c'est ce qu'on va faire
(12:14:36) davin.baragiotta: 3. les retardataires peuvent suivre les instructions d'hier en résumé
(12:15:03) davin.baragiotta: voici aussi un condensé de ce qu'on a fait hier préparé hier par progfou pendant qu'il modérait mon atelier
(12:15:19) davin.baragiotta: 

‎sudo apt-get install virtualenv
mkdir ~/django ; cd ~/django
virtualenv atelier ; cd atelier
source bin/activate
pip install Django==1.4.6 south==0.7.6
python
import django
django.get_version() # vérifier que ça donne bien 1.4.6
exit()
django-admin.py startproject carto ; cd carto
ls -lR # observer les fichiers
# ouvrir http://127.0.0.1:8000/ dans un navigateur web
[ctrl]+[c]
edit carto/settings.py # mettre 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'carto.db' et LANGUAGE_CODE = 'fr-fr'
python manage.py startapp annuaire
ls -lR annuaire
edit annuaire/models.py # remplir avec https://coderpad.io/771405
# visiter https://docs.djangoproject.com/en/1.4/topics/db/models/ pour les détails
# visiter https://docs.djangoproject.com/en/1.4/ref/models/fields/ pour les détails
edit carto/settings.py # ajouter 'annuaire' et dé-commenter admin dans INSTALLED_APPS
edit carto/urls.py # décommenter les 4 lignes pour l'admin
edit annuaire/admin.py # remplir avec https://coderpad.io/771405
# visiter https://docs.djangoproject.com/en/1.4/ref/contrib/admin/ pour les détails
python manage.py syncdb # créer un compte admin
python manage.py runserver # ouvrir http://127.0.0.1:8000/admin/ dans un navigateur web

(12:15:40) davin.baragiotta: voilà... donc là on repart pour vrai
(12:16:29) davin.baragiotta: habituellement, quand on termine l'atelier Backend... on a des modèles plus intéressants que ceux qu'on a pu faire hier
(12:16:50) davin.baragiotta: notamment, on a lié les Personnes avec les Établissements....
(12:17:11) davin.baragiotta: aussi... on part avec un jeu de données qu'on a saisi dans l'admin
(12:17:40) davin.baragiotta: donc on va d'abord faire ça : améliorer nos modèles et saisir des données
(12:17:57) davin.baragiotta: (puisqu'aujourd'hui... on veut présenter des données dans interfaces publiques... faut bien les avoir!)
(12:18:08) davin.baragiotta: éditer le fichiers models.py
(12:18:14) davin.baragiotta: il dans notre app annuaire
(12:18:23) davin.baragiotta: /django/carto/annuaire/models.py
(12:18:44) davin.baragiotta: je code live ici : https://coderpad.io/771405
(12:19:02) davin.baragiotta: (si vous vous y connectez, mettez votre nom, c'est plus sympa que Guest...)
(12:19:44) davin.baragiotta: sur les modèles.... quand un champs n'est pas requis, dans Django
(12:19:52) davin.baragiotta: on ajoute le paramètre : null=True
(12:20:09) davin.baragiotta: (j'accepte que ce champ puisse être null)
(12:20:53) davin.baragiotta: je baisse aussi le nombre de caract pour un sigle
(12:21:31) davin.baragiotta: maintenant je vais lier Personne et Etablissement
(12:21:55) davin.baragiotta: je veux dire qu'une Personne peut appartenir à un Etablissement
(12:23:04) davin.baragiotta: voilà
(12:23:29) davin.baragiotta: assurez-vous que vous ayiez le même code que celui dans le pad... et copiez-le dans votre fichier models.py
(12:23:31) davin.baragiotta: save
(12:24:11) davin.baragiotta: bien, maintenant... on vient de modifier la structure d'info qu'on veut avoir sur une Personne...
(12:24:42) davin.baragiotta: ... mais cette info est stockée en base de données... on veut donc pouvoir stocker notre nouveau champ "universite"
(12:25:04) davin.baragiotta: il faut que la DB soit synchronisée avec ce qu'on a dans les modèles
(12:25:22) davin.baragiotta: actuellement... tout ce qu'on peut faire : c'est supprimer la DB
(12:25:25) davin.baragiotta: et la recréer
(12:25:34) davin.baragiotta: pour supprimer la DB :
rm carto.db
(12:25:53) davin.baragiotta: oui... vous allez perdre toutes les données déjà saisies
(12:25:56) davin.baragiotta: c'est nul
(12:26:23) davin.baragiotta: pour éviter ça... et permettre de faire évoluer la DB parallèlement à l'évolution des modèles
(12:26:29) davin.baragiotta: sans qu'on perde de données
(12:26:37) davin.baragiotta: on va utiliser un outil qui s'appelle South
(12:27:00) davin.baragiotta: olivier vous montrera ça dans le prochain atelier Django à 12h30 UTC aujourd'hui
(12:27:09) davin.baragiotta: donc votre DB est supprimeé
(12:27:14) davin.baragiotta: on va la recréer :
(12:27:40) davin.baragiotta: ah oui, votre environnement virtuel doit être activé :
(12:28:11) davin.baragiotta: 
~/django$ source atelier/bin/activate
(12:28:57) davin.baragiotta: ensuite :
cd carto
(12:29:28) davin.baragiotta: puis :
(atelier)~/django/carto$ python manage.py syncdb
(12:30:07) davin.baragiotta: créer superuser de l,admin : admin/admin
(12:30:36) davin.baragiotta: allons ensuite saisir des données :
(12:30:49) davin.baragiotta: 
(atelier)~/django/carto$ python manage.py runserver
(12:30:57) davin.baragiotta: dans un navigateur, aller à :
(12:31:33) davin.baragiotta: http://127.0.0.1:8000/admin/
(12:31:42) davin.baragiotta: saisissez quelques données pour Etablissement
(12:31:44) davin.baragiotta: ensuite
(12:31:50) davin.baragiotta: quelques données pour Personne...
(12:32:01) davin.baragiotta: (lier Personnes à Etablissement)
(12:32:05) davin.baragiotta: des questions?
(12:33:44) davin.baragiotta: bon, 2 trucs nuls actuellement
(12:34:08) davin.baragiotta: 1. mon champ date de naissance est obligatoire, même si j'ai dit "null=True"
(12:34:16) arnaud.amelina@auf.org: Pas pour le moment
(12:34:29) davin.baragiotta: 2. Dans la liste de mes objets... je vois "Etablissement object"...
(12:34:42) davin.baragiotta: pas simple donc de distinguer entre 2 établissements...
(12:34:45) davin.baragiotta: on va corriger ça
(12:34:50) davin.baragiotta: de retour dans le pad :
(12:34:58) davin.baragiotta: https://coderpad.io/771405
(12:35:24) davin.baragiotta: blank=True
(12:35:45) davin.baragiotta: ça veut dire que c'est permis dans les formulaires de ne pas choisir de valeur
(12:36:07) davin.baragiotta: (un peu étrange comme nuance d,avec null... mais lire la doc au besoin pour plus de précision)
(12:36:27) davin.baragiotta: (on ne devrait pas avoir à refaire syncdb, car ça n'impacte pas la DB)
(12:36:29) davin.baragiotta: save
(12:36:43) davin.baragiotta: tester dans interface admin si date de naissance d'une personne = obligatoire
(12:37:32) davin.baragiotta: parfait, ça marche
(12:37:46) davin.baragiotta: (faire pareil pour université, au besoin)
(12:38:04) davin.baragiotta: bon l'autre astuce, pour l,affichage c'est 
def __unicode__():
(12:38:33) davin.baragiotta: cette fonction interne (car entourée de __ : en Python ça veut dire inter... utilisé par Python)
(12:39:03) davin.baragiotta: cette focntion donc, décrit comment l'objet de cette classe doit être visuellement représenté
(12:39:15) davin.baragiotta: quelle chaine de caractère retourner pour voir cet objet
(12:39:29) davin.baragiotta: c'est comme un "ToString" en Java
(12:39:39) davin.baragiotta: je code dans le pad
(12:41:05) davin.baragiotta: ok, ça va faire le boulot
(12:41:39) davin.baragiotta: en gros, pour un Etablissement ou une Personne : on affiche maintenant seulement son nom dans les listings de l'admin
(12:41:41) davin.baragiotta: voilà
(12:41:42) davin.baragiotta: save
(12:41:52) davin.baragiotta: refresh page listing dans admin
(12:42:30) davin.baragiotta: pareil : pas besoin de refaire syncdb... ces modifs n'impacte pas DB
(12:43:26) davin.baragiotta: NOTE : j'accepte les questions en cours de route, via le modérateur dans le salon tech
(12:43:46) davin.baragiotta: ok, alors saisissez quelques données
(12:44:06) davin.baragiotta: PARTIE 2 : FRONTEND (INTERFACES PUBLIQUES)
(12:44:25) davin.baragiotta: bon, là on comment formellement notre atelier car on a rattrapé le retard d'hier
(12:44:36) ongolaBoy: sekou.diall: Question : page listing, c'est au niveau de la page d'accueil ? 
(12:44:48) davin.baragiotta: oui, cliquer sur Etablissement ou Personne
(12:45:00) davin.baragiotta: c'est la liste des objets pour ces 2 modèles
(12:45:44) davin.baragiotta: À date : on n'a jamais codé de réponse HTTP (HTML/CSS) à une requête web
(12:45:53) davin.baragiotta: c'est l'admin Django qui fait tout à notre place
(12:46:13) davin.baragiotta: dans la vraie vie : les utilisateurs ne vont pas tous dans l'admin Django
(12:46:29) davin.baragiotta: on va présenter, pour eux, des infos dans le Frontend
(12:46:39) davin.baragiotta: c'est un peu comme la métaphore suivante :
(12:46:52) davin.baragiotta: cuisine = backend.... le restaurant = frontend
(12:47:05) davin.baragiotta: ou entrepôt = backend... magasin = frontend
(12:47:13) davin.baragiotta: voilà donc allons créer notre boutique ;)
(12:47:20) davin.baragiotta: déjà, on veut une page d'accueil
(12:48:16) davin.baragiotta: pour retourner une page d'accueil... on va devoir modifier les fichiers dans cet ordre :
urls.py
views.py
templates
(12:48:31) davin.baragiotta: (ordre logique... aucun impact de le faire dans le désordre)
(12:48:31) davin.baragiotta: donc
(12:49:01) davin.baragiotta: d'abord... on doit avoir une "route" dans nos urls pour la page d'accueil
(12:49:11) davin.baragiotta: en général on veut que / soit la page d'accueil
(12:49:23) davin.baragiotta: 127.0.0.1:8000/
(12:49:30) davin.baragiotta: actuellement on a une erreur
(12:49:37) davin.baragiotta: http://127.0.0.1:8000/
(12:49:57) davin.baragiotta: car on n'a qu'une seule route... qu'un seul patron d'URL : celui vers l'admin
(12:50:03) davin.baragiotta: modifions urls.py
(12:50:11) davin.baragiotta: je vais dans le pad
(12:50:43) davin.baragiotta: je décommente la route pour l'accueil
(12:51:21) davin.baragiotta: ^ et $ ont un sens spécial
(12:51:33) davin.baragiotta: on entre dans l'univers des "expressions régulières"
(12:51:40) davin.baragiotta: c'est un monde syntaxique en soit
(12:52:06) davin.baragiotta: ça sert à vérifier si une chaîne de caract répond bien au patron
(12:52:11) davin.baragiotta: toute la doc est ici :
(12:52:36) davin.baragiotta: http://docs.python.org/2/library/re.html
(12:53:03) davin.baragiotta: je viens de décommenter l'url pour accueil
(12:53:11) davin.baragiotta: 
url(r'^$', 'carto.views.home', name='home'),
(12:53:26) davin.baragiotta: les 3 param de la focntion url() se lisent ainsi :
(12:53:36) davin.baragiotta: 1. patron d'url : ^$
(12:53:58) davin.baragiotta: 2. la fonction qui fera le boulot pour construire la réponse HTTP
(12:54:15) davin.baragiotta: 3. un nom pour cette URL gérée... sera utile dans les templates
(12:54:32) davin.baragiotta: (pour construire dynamique l'URL vers l'accueil)
(12:54:44) davin.baragiotta: conclusion? et bien... me faut maintenant la fonction
(12:54:53) davin.baragiotta: qui réclame mon fichier urls.py
(12:55:09) davin.baragiotta: la fonction carto.views.home
(12:55:26) davin.baragiotta: donc allons dans carto, éditer le fichiers views... pour y coder la fonction home
(12:55:50) davin.baragiotta: éditer django/carto/carto/views.py
(12:55:59) davin.baragiotta: je suis sur le pad
(12:56:10) davin.baragiotta: en bas complètement
(12:57:28) davin.baragiotta: j'importe une fonction fournie par Django (c'est le but du framework... m'aider)
(12:57:32) davin.baragiotta: render
(12:57:42) davin.baragiotta: va me permettre de faire le rendu d'un template HTML
(12:58:17) davin.baragiotta: le premier param que Django passe à toutes nos views : request...
(12:58:31) davin.baragiotta: y'a plein d'info sur la requête HTTP faites par le user
(12:59:58) davin.baragiotta: les fonctions dans views, retournent le rendu d'un fichier HTML
(13:00:14) davin.baragiotta: on passe aussi request au template (au cas où on en aurait besoin)
(13:00:21) davin.baragiotta: onn donne le nom du template voulu
(13:00:30) davin.baragiotta: home.html
(13:01:05) davin.baragiotta: et aussi... on va passer des varaibles au template
(13:01:27) davin.baragiotta: le but de views est de préparer les variables qu'on passe au template
(13:02:20) davin.baragiotta: on va revenir sur les variables
(13:02:32) davin.baragiotta: voivi donc le code à mettre dans le views.py de carto/
(13:02:41) davin.baragiotta: 
from django.shortcuts import render

def home(request):
# coder le traitement voulu ici... on va y revenir

c = { 
}
return render(request, 'home.html', c)
(13:02:46) davin.baragiotta: c'est pas grand chose!
(13:03:17) davin.baragiotta: ok...
(13:03:29) davin.baragiotta: views.py n'existait pas dans carto... je l'ai créé
(13:03:55) davin.baragiotta: c'est un choix de design (l'accueil est globale... pas propre à mon application "annuaire")
(13:04:11) davin.baragiotta: donc créez : 
django/carto/carto/views.py
(13:04:18) davin.baragiotta: si n'existait pas
(13:04:24) davin.baragiotta: (question qu'on ait le même code)
(13:04:37) davin.baragiotta: et mettez-y le code plus haut
(13:04:41) davin.baragiotta: bon
(13:04:46) davin.baragiotta: si on se rappelle notre séquence :
(13:05:14) davin.baragiotta: on a un urls.py qui passe la main à la fonction home si l'URL demandée est celle de l'accueil...
(13:05:40) davin.baragiotta: la fonction home... elle est fait le rendu du template HTML "home.html" (qu'on n'a pas encore créé)
(13:05:59) davin.baragiotta: voyons ce qui se passe si on essaie de voir l'accueil de notre site
(13:06:11) davin.baragiotta: (votre serveur doit tourner, si ce n'est pas le cas :)
(13:06:53) davin.baragiotta: 
(atelier)~/django/carto$ python manage.py runserver
(13:07:43) davin.baragiotta: http://127.0.0.1:8000/
(13:07:50) davin.baragiotta: TemplateDoesNotExist at /
(13:07:57) davin.baragiotta: home.html
(13:08:07) davin.baragiotta: j'ai cette erreur ^
(13:08:31) davin.baragiotta: normal, on le sait... on n'a pas codé le template home.html encore
(13:08:36) davin.baragiotta: prêt à coder le template?
(13:08:39) davin.baragiotta: des questions?
(13:09:36) davin.baragiotta: bon super... hey! on n'est pas loin d'avoir notre première page HTML propulsée par Django!
(13:09:52) davin.baragiotta: https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support
(13:10:13) davin.baragiotta: Je suis à "Flux d'info de requête à réponse"... le point sur les templates
(13:10:34) davin.baragiotta: comme on avait vu la doc hier sur les modèle Django
(13:10:43) davin.baragiotta: on a de la doc évidemment sur les Templates
(13:10:54) davin.baragiotta: regardons encore un coup l'accueil de la doc Django
(13:11:13) davin.baragiotta: https://docs.djangoproject.com/en/dev/
(13:11:24) davin.baragiotta: attention, choisir en bas à droite la version de votre Django
(13:11:33) davin.baragiotta: on a 1.4.6... donc la doc pour 1.4
(13:11:45) davin.baragiotta: https://docs.djangoproject.com/en/1.4/
(13:11:55) davin.baragiotta: ok on a ceci sur l'accueil
(13:12:04) davin.baragiotta: * first steps : c'est ce qu'on fait là!
(13:12:27) davin.baragiotta: * model layer : on en a parlé hier, on y reviendra avec olivier dans l'autre atelier
(13:12:50) davin.baragiotta: * template layer : tadaaaaam c'est là où on est actuellement
(13:13:09) davin.baragiotta: * view layer : on vient de coder notre première focntion de view, home()
(13:13:29) davin.baragiotta: * forms : on n'en parlera pas ici... voir tuto Django, section 4
(13:13:48) davin.baragiotta: * dev process : on n'en parle pas... regardez au besoin
(13:13:59) davin.baragiotta: * other batteries included : on a vu l'admin hier!
(13:14:06) davin.baragiotta: maintenant... template!
(13:14:39) davin.baragiotta: on va aller dans le fihciers settings pour dire à Django où aller chercher nos templates
(13:14:51) davin.baragiotta: éditer carto/carto/settings.py
(13:15:24) davin.baragiotta: on n'a pas fait le tour hier de tous les params... vous pourrez le faire... mais on peut changer plein de trucs utiles
(13:15:31) davin.baragiotta: comme la langue par défaut : 
(13:15:47) davin.baragiotta: LANGUAGE_CODE = 'en-us'
(13:15:53) davin.baragiotta: LANGUAGE_CODE = 'fr-ca'
(13:16:03) davin.baragiotta: ou 'fr-fr' hein! on n'est pas raciste ;)
(13:16:17) davin.baragiotta: cherchez ce param de configuration :
(13:16:33) davin.baragiotta: TEMPLATE_DIRS
(13:16:45) davin.baragiotta: assurez-vous d'avoir ceci :
(13:17:01) davin.baragiotta: 
TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), "templates"), )
(13:17:33) davin.baragiotta: je le mets dans le pad de code... pour mieux le formatter
(13:18:35) davin.baragiotta: ok lisons un peu ce code que je n'ai pas voulu taper moi-même ;)
(13:18:49) davin.baragiotta: globalement on dit à Django "mes templates seront là"
(13:19:06) davin.baragiotta: le là en question, c'est : dans un répertoire "templates"
(13:19:41) davin.baragiotta: qui se trouve au même endroit que le fichier en cours (settings.py, donc)
(13:19:56) davin.baragiotta: je passe les détails de la manipulation de os
(13:20:08) davin.baragiotta: mais vu qu'on utilise le module "os" de python...
(13:20:15) davin.baragiotta: ... et bien, il faut l'importer
(13:20:21) davin.baragiotta: en haut du fichier de settings.py, ajouter
(13:20:23) davin.baragiotta: import os
(13:20:53) davin.baragiotta: voilà
(13:21:21) davin.baragiotta: maintenant que Django sait que mes templates sont dans un répertoire "templates"
(13:21:30) davin.baragiotta: créons ce répertoire dans carto/carto
(13:21:40) davin.baragiotta: créer : carto/carto/templates
(13:22:16) davin.baragiotta: rappellons nous encore le chainage :
(13:22:26) davin.baragiotta: urls.py > views.py > templates
(13:22:42) davin.baragiotta: ma fonction home() de views.py... veut le template 'home.html'
(13:22:47) davin.baragiotta: on va le créer
(13:23:00) davin.baragiotta: créer carto/carto/templates/home.html
(13:23:12) davin.baragiotta: voilà... éditer home.html
(13:23:22) davin.baragiotta: et laisser aller votre talent en HTML ;)
(13:23:45) davin.baragiotta: disons qu'on commence par une pseudo page HTML que je code dans le pad
(13:25:53) davin.baragiotta: 
# carto/templates/home.html
<html>
<head>
<title>Carotgraphie des membres</title>
</head>
<body>
<h1>Accueil</h1>
<p>Alors, ça s'affiche?</p>
</body>
</html>
(13:26:06) davin.baragiotta: sauvegarder home.html avec ce contenu
(13:26:15) davin.baragiotta: refesh accueil dans navigateur
(13:26:51) davin.baragiotta: relancer serveur au besoin
(13:27:28) davin.baragiotta: voilà votre première page HTML propulsée par Django!
(13:27:34) davin.baragiotta: questions?
(13:28:21) ongolaBoy: Q: je constate que le serveur web se recharge souvent tout seul.. Comment sait-il que des fichiers sont modifiés ?
(13:29:06) davin.baragiotta: honnêtement je ne sais pas trop...
(13:29:32) davin.baragiotta: mais il faut savoir que ce n'est qu'un serveur de DEV... rien à voir avec la mécanique en PROD...
(13:30:06) davin.baragiotta: (disons que la partie serveur m'intéresse moins que le code de mon app ;) )
(13:30:18) davin.baragiotta: (serveur de DEV, j'entends)
(13:30:46) davin.baragiotta: ok on continue, reste 30 minutes
(13:31:02) davin.baragiotta: là notre page est plutôt nulle... à plusieurs égards
(13:31:29) davin.baragiotta: d'abord, c'est une page HTML statique... on n'a pas besoin de Python pour ça
(13:31:48) davin.baragiotta: actuellement, ma page d'accueil est invariable...
(13:32:00) davin.baragiotta: on va donc lui passer une variable
(13:32:10) davin.baragiotta: aller dans views.py... fonction home()
(13:32:17) davin.baragiotta: je suis dans le pad
(13:32:41) davin.baragiotta: on a créé un dictionnaire Python (vide actuellement)
(13:32:57) davin.baragiotta: qu'on a nommé "c"... (souvent ça par convention)
(13:33:17) davin.baragiotta: et on a passé c au template... dans notre fonction rendre... ligne 62 du pad
(13:33:44) davin.baragiotta: le but de "c" est de contenir toutes les variables qu'on veut passer au template...
(13:33:46) davin.baragiotta: codons
(13:35:16) davin.baragiotta: voilà... assurez-vous d'avoir le corps de la fonction home() codée dans le pad
(13:35:25) davin.baragiotta: 
from django.shortcuts import render

def home(request):
# coder le traitement voulu ici... on va y revenir

prenom = "Davin"
nom = "Baragiotta"

c = {
'usager':nom,
}
return render(request, 'home.html', c)
(13:35:40) davin.baragiotta: allez dans votre template : home.html en édition
(13:36:07) davin.baragiotta: et dans le corps de la page, on a utiliser la variable "usager" qui a été passée au template
(13:36:13) davin.baragiotta: de retour dans le pad
(13:37:06) davin.baragiotta: nouveau ; ligne 78 du pad
<html>
<head>
<title>Carotgraphie des membres</title>
</head>
<body>
<h1>Accueil</h1>
<p>Alors, ça s'affiche?</p>
<p>Salut : {{ usager }}</p>
</body>
</html>
(13:37:33) davin.baragiotta: {{ variable }} : c,est la syntaxe pour afficher une variable
(13:37:42) davin.baragiotta: on N'est PLUS dans du Python là
(13:37:50) davin.baragiotta: on est dans un langage de "templating"
(13:38:04) davin.baragiotta: Django a son propre langage de templating, documenté ici :
(13:38:18) davin.baragiotta: https://docs.djangoproject.com/en/1.4/topics/templates/
(13:38:40) davin.baragiotta: de l'accueil de la doc : sous "template layer"... "syntax overview"
(13:38:54) davin.baragiotta: ok save home.html
(13:38:58) davin.baragiotta: refresh page accueil
(13:39:57) davin.baragiotta: attention à l'indentation dans les fichiers Python
(13:40:15) davin.baragiotta: (mon copié-collé de views a mal indenté ligne avec prenom)
(13:40:48) davin.baragiotta: voilà, vous devriez voir le contenu de la variable nom de la views
(13:40:55) davin.baragiotta: 2 remarques avant de continuer
(13:41:06) davin.baragiotta: si on regarde le code dans views.py
(13:41:54) davin.baragiotta: on voit qu'on n'a jamais mis "prenom" dans la variable "c"... donc le template home.html ne devrait pas avoir accès à la variable "prenom"
(13:41:57) davin.baragiotta: essayez
(13:42:18) davin.baragiotta: {{ prenom }} : n'affiche rien si on l'ajoute au template
(13:43:00) davin.baragiotta: donc le "c" : nous permet de choisir les variables qui passent au template... et celles qui restent locales à la fonction home()
(13:43:10) davin.baragiotta: (c'est bien : on veut pas passer n'importe quoi)
(13:43:25) davin.baragiotta: aussi... par convention, on va essayer de garder les choses simples
(13:43:45) davin.baragiotta: de la même façon que ma fonction s'appelle home, le template s'appelle home
(13:44:05) davin.baragiotta: aussi... si je veux passer le contenu de "nom"... bien autant l'appeler "nom" et pas "usager"
(13:44:17) davin.baragiotta: (avec le code actuel... comme "prenom"... "nom" n'affiche rien)
(13:44:40) davin.baragiotta: donc les "clés" du dictionnaire "c" sont les noms de variables à utiliser dans le template
(13:45:01) davin.baragiotta: modifions le code de views pour mettre les choses claires... et modifions le template :
(13:45:27) davin.baragiotta: modifié dans le pad... je vous laisse le faire en local
(13:45:50) ongolaBoy: progfou: Q: as-tu prévu de parler de l'héritage des templates ? c'est typiquement utile pour séparer le squelette du site (base.html) des pages de contenu (home.html, about.html, …) qui en héritent ensuite
(13:46:06) davin.baragiotta: voir plan de présentation ;)
(13:46:07) davin.baragiotta: oui
(13:46:15) davin.baragiotta: mais on n'aura pas le temps... je vais le mentionner
(13:46:22) davin.baragiotta: je reprends :
(13:46:44) davin.baragiotta: notre page est toujours nulle : elle affiche une variable qui est déclarée en dur!
(13:46:51) davin.baragiotta: (qui ne varie pas donc!)
(13:47:04) davin.baragiotta: pourquoi ne pas lister les établissements en page d'accueil?
(13:47:06) davin.baragiotta: :)
(13:47:30) davin.baragiotta: oui, les établissements qu'on a saisi dans l'admin et qui sont actuellement stockés dans la DB sqlite3 : carto.db
(13:47:44) davin.baragiotta: pour ça... on entre dans le monde de l'ORM :
(13:47:49) davin.baragiotta: object-relation mapping
(13:47:54) davin.baragiotta: *relational
(13:48:26) davin.baragiotta: concrètement... on va utiliser modèles pour accéder aux infos de la DB
(13:48:32) davin.baragiotta: codons dans le pad
(13:48:58) davin.baragiotta: je suis dans home()
(13:49:51) davin.baragiotta: j,ai ajouté ligne 62 et ligne 57
(13:50:11) davin.baragiotta: et 69
(13:50:20) davin.baragiotta: 
from django.shortcuts import render

from annuaire.models import Etablissement

def home(request):
# coder le traitement voulu ici... on va y revenir

etablissements = Etablissement.objects.all()

prenom = "Davin"
nom = "Baragiotta"

c = {
'nom': nom,
'etablissements':etablissements,
}
return render(request, 'home.html', c)
(13:50:39) davin.baragiotta: en 3 lignes, je vais chercher tous mes établissements et je les passe au template home.html
(13:50:48) davin.baragiotta: codez
(13:50:50) davin.baragiotta: save
(13:51:19) davin.baragiotta: on va miantenant afficher les établissements
(13:51:29) davin.baragiotta: dans la mesure où je n'ai pas qu'une seule valeur
(13:51:34) davin.baragiotta: (car plusieurs établissements)
(13:51:36) davin.baragiotta: je vais boulcer
(13:51:44) davin.baragiotta: *boucler dans le template
(13:51:51) davin.baragiotta: je suis dans home.html dans le pad
(13:53:24) davin.baragiotta: ajouté :
(13:53:26) davin.baragiotta: 
<ul>
{% for e in etablissements %}
<li>{{ e }}</li>
{% enfor %}
</ul>
(13:53:31) davin.baragiotta: save home.html
(13:53:47) davin.baragiotta: refresh page accueil
(13:54:03) davin.baragiotta: Invalid block tag: 'enfor', expected 'empty' or 'endfor'
(13:54:12) davin.baragiotta: oui... c'est endfor... pas enfor
(13:54:17) davin.baragiotta: je modifi dans pad
(13:54:49) davin.baragiotta: voilà
(13:55:11) davin.baragiotta: pour terminer... je vous montre la doc de l'ORM : comment accéder aux objets en DB
(13:55:24) davin.baragiotta: (et pas seulement "tous" les sélectionner)
(13:55:57) davin.baragiotta: c'est dans "model layer"... QuerySets... Executing queries
(13:56:05) davin.baragiotta: 
https://docs.djangoproject.com/en/1.4/topics/db/queries/
(13:56:15) davin.baragiotta: pour pouvoir vous amusez avec l'ORM
(13:56:32) davin.baragiotta: par exemple, prendre que certains objets avec .filter()
(13:57:30) davin.baragiotta: Django offre la possibilité de lancer l'interpréteur Python... avec l'environnement de Django déjà préchargé :
(atelier)~django/carto$ python manage.py shell
(13:57:55) davin.baragiotta: voir plan de présentaiton, "ORM : exploration interactive"
(13:57:55) davin.baragiotta: https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support
(13:58:23) davin.baragiotta: le but est, comme toujours, d'explorer dans le shell le bon code Python qu'on veut
(13:58:34) davin.baragiotta: et ensuite... on met le code Python dans notre fonction views.py
(13:58:44) davin.baragiotta: def home()... par exemple
(13:59:03) davin.baragiotta: voilà... prenons un instant pour regarder ce qui n'a pas été couvert dans le doc de présentation
(13:59:04) davin.baragiotta: https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support
(13:59:29) davin.baragiotta: * l'ORM... dont je viens de vous parler
(13:59:48) davin.baragiotta: * l'héritage de templage... dont progfou parlait
(14:00:10) davin.baragiotta: (car on veut pas coder tout le <html><head>... dans cahque page)
(14:00:44) davin.baragiotta: aussi comment gérer des URLs de la forme 
127.0.0.1:8000/etablissement/134
(14:00:56) davin.baragiotta: où 134 = id pour accéder à un établissement en particulier
(14:01:26) davin.baragiotta: aussi, on veut des pages belles : pas juste noir et blanc (comme les profs d'université ;) )
(14:01:41) davin.baragiotta: donc comment utiliser les fichiers statiques
(14:01:57) davin.baragiotta: voilà... y'aurait de la maitère pour plus... mais on a atteint notre objectif :
(14:02:18) davin.baragiotta: vous avez les bases minimales pour afficher des données (provenant de DB) dans le frontend :
(14:02:31) davin.baragiotta: urls.py > views.py > templates
(14:02:36) davin.baragiotta: des questions?
(14:02:57) davin.baragiotta: (reste plus trop de temps... mais je suis toujours présent sur jabber, même hors semaine tech) ;)
(14:03:26) ongolaBoy: c'est terminé mais il reste 27 minutes avant le prochain atelier
(14:03:57) progfou: ouais, et on est tou{te,}s du genre à manger sur notre clavier, non ? ;-)
(14:05:11) ongolaBoy: --------------------------------------------------------- FIN ATELIER DJANGO : Frontend ----------------------------------------------------

Projet/SemaineTech/2013/Ateliers/DjangoFrontend/Archive (dernière édition le 2013-09-06 11:17:31 par YemenSayour)