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 ----------------------------------------------------