davin.baragiotta 31/08/2012 02:17:07 ---------------------------------- DÉBUT ATELIER DJANGO FRONTEND ------------------------------ {{{#!python Bonjour à tous 31/08/2012 02:17:11 https://wiki.auf.org/wikiteki/Projet/SemaineTech/2012/Ateliers/DjangoFrontend 31/08/2012 02:17:42 l'atelier Django Frontend est une suite logique de l'atelier Django Architecture d'un projet et backend 31/08/2012 02:18:03 mais peut être suivi indépendamment 31/08/2012 02:18:13 il est annoncé pour Django 1.4 et Django 1.1.1 31/08/2012 02:18:25 mais ce sera plus simple pour Django 1.1.1 car tout le matériel est prêt 31/08/2012 02:18:39 (1.4 devrit être prêt pour prochaine édition de cet atelier... plus tard en journée) 31/08/2012 02:18:58 la page de l,atelier.... le contenu de la présentation est ici : 31/08/2012 02:19:12 https://wiki.auf.org/wikiteki/Ateliers/Django/Backend/Support 31/08/2012 02:19:23 ach non! 31/08/2012 02:19:37 ici plutôt : 31/08/2012 02:19:42 https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support 31/08/2012 02:19:55 INTRODUCTION 31/08/2012 02:20:00 Notre objectif aujourd'hui 31/08/2012 02:20:11 est de présenter les données qu'on sait maintenant gérer dans l,admin 31/08/2012 02:20:23 les présentées au public dans des interfaces publiques 31/08/2012 02:20:32 la documentation Django est au même endroit qu'hier 31/08/2012 02:20:58 je sais que ceux qui suivent étaient là hier... 31/08/2012 02:21:11 maintenant, le contenu couvert ici équivaut au contenu de la 3e partie du tutoriel officiel 31/08/2012 02:21:36 je passe l'environnement technique... si il y a des nouveaux, vous manifester dans tech svp... Tri est modérateur 31/08/2012 02:22:00 RAPPELS ET AMORCE DU PROJET 31/08/2012 02:22:11 on veut pas repartir de zéro... 31/08/2012 02:22:19 c'est à dire qu'on veut pas 31/08/2012 02:22:29 recréer un projet, une app... faire toute la config... créer des modèles 31/08/2012 02:22:39 donc je vous ai donné des sources pour qu'on parte tous avec les mêmes bases 31/08/2012 02:23:01 Django 1.1.1 31/08/2012 02:23:04 https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support%3Faction%3DAttachFile%26do%3Dget%26target%3Dcarto_1_1_backend_final.tar.gz 31/08/2012 02:23:12 je vous laisse télécharger 31/08/2012 02:23:20 l'intérêt de cette archive 31/08/2012 02:23:28 c'est qu'elle correspondant au code complet final de l'atelier Backend 31/08/2012 02:23:50 on a même un jeu de données rigolo que j'ai saisi 31/08/2012 02:24:00 ah, pour ceux que ça intéresse 31/08/2012 02:24:07 l'ensemble des manips de l'atelier Backend et Frontend 31/08/2012 02:24:22 se trouve suivies dans git... 31/08/2012 02:24:28 Tri 31/08/2012 02:24:30 Cette page n'existe pas encore.! davin.baragiotta 31/08/2012 02:24:33 dans mon dépôt perso ok minute... je charge l'archive 31/08/2012 02:24:56 https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support?action=AttachFile&do=get&target=carto_1_1_backend_final.tar.gz 31/08/2012 02:25:41 Tri 31/08/2012 02:26:10 c'est bon! davin.baragiotta 31/08/2012 02:26:34 super... je vous laisse dépaqueter 31/08/2012 02:26:46 faire un petit : python manage.py runserver 31/08/2012 02:27:03 regarde un coup dans l'admin pour voir les données : 31/08/2012 02:27:13 http://127.0.0.1:8000/admin 31/08/2012 02:27:26 questions? 31/08/2012 02:28:51 tout marche? 31/08/2012 02:28:54 Tri 31/08/2012 02:29:33 [09:28:44] Khone: Question: Les codes dans JP est pareil que hier (pour tous ce qui est fini) ? davin.baragiotta 31/08/2012 02:29:56 JP ? le code dans l,archive est pareil et plus que hier 31/08/2012 02:30:13 j'ai ajouté 2-3 trucs dans models.py et admin.py 31/08/2012 02:30:27 si vous avez votre code d'hier : pas de probl... 31/08/2012 02:30:36 Tri 31/08/2012 02:30:40 [09:30:38] Khone: Pièce-Joint (JP) davin.baragiotta 31/08/2012 02:30:42 avez juste des données.... c'est nul de faire des listes d'un élément dans les interfaces 31/08/2012 02:31:03 ok.... je considère qu'on est tous ensemble dans le nouveau code de l,archive en Django 1.1.1 31/08/2012 02:31:36 Tri 31/08/2012 02:31:44 ca marche pour Huy et khuon davin.baragiotta 31/08/2012 02:32:19 c'est important qu'on soit tous ok tous : je présente dans la doc 3 options pour les sources : 31/08/2012 02:32:36 https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support#Amorce_du_projet 31/08/2012 02:32:41 télécharger l'archive est une approche 31/08/2012 02:32:52 ok on part pour vrai 31/08/2012 02:34:49 FRONTEND 31/08/2012 02:34:59 l'idée d'un frontend vs backend 31/08/2012 02:35:10 c'est un peu comme une boutique et son arrière boutique 31/08/2012 02:35:21 phouvichit.xongmixay a rejoint le salon 02:35 davin.baragiotta 31/08/2012 02:35:48 y'a des trucs qu'on veut pas offir au client : backend le reste = frontend 31/08/2012 02:35:51 nous on code les interfaces publiques 31/08/2012 02:35:58 vous vous rappelez du schéma de dev web en Django? 31/08/2012 02:36:11 http://montrealpython.org/r/attachments/13/web-development.jpg 31/08/2012 02:36:20 là... on va passer dans tous les fichiers : 31/08/2012 02:36:32 dans cet ordre : 31/08/2012 02:36:36 urls.py 31/08/2012 02:36:37 views.py 31/08/2012 02:36:40 templates 31/08/2012 02:36:42 on va commecner par se créer une page d'accueil 31/08/2012 02:36:55 pas con, hein? 31/08/2012 02:36:58 la requête pour la page d,accueil = le root de notre nom de domaine 31/08/2012 02:37:18 / 31/08/2012 02:37:22 en localhost, ça donne : 31/08/2012 02:37:33 http://127.0.0.1:8000 31/08/2012 02:37:42 ou 31/08/2012 02:37:45 http://127.0.0.1:8000/ 31/08/2012 02:37:50 tapez cette URL dans notre navigateur 31/08/2012 02:38:05 python manage.py runserver doit rouler 31/08/2012 02:38:14 vous devez avoir une erreur 31/08/2012 02:38:38 shafeek.sumser 31/08/2012 02:38:44 oui davin.baragiotta est en Django 1.4.... je suis pas des masses 02:38 davin.baragiotta 31/08/2012 02:38:58 normal tran.xuan.huy a quitté la salle 02:39 davin.baragiotta 31/08/2012 02:39:16 ça doit dire que y,a pas d'URL pour ça Tri a quitté la salle 02:39 davin.baragiotta 31/08/2012 02:39:50 donc on va coder l'urls qui gère le / dans views.py 31/08/2012 02:39:54 non... dans urls.py 31/08/2012 02:40:07 éditer le fichier 31/08/2012 02:40:13 on va ajouter un ligne 31/08/2012 02:40:19 url(r'^$', 'carto_1_1.views.home', name='home'), 31/08/2012 02:40:29 Tri a rejoint le salon 02:40 davin.baragiotta 31/08/2012 02:41:03 carto_1_1 = facultatif... et s'appelle comme ça pour ceux ayant télécahrger les sources... c'est le nom du projet ça se lit comme suit : 31/08/2012 02:41:07 Tri a quitté la salle 02:41 tran.xuan.huy a rejoint le salon 02:41 davin.baragiotta 31/08/2012 02:41:39 on édite le fichier suivant : carto_1_1/urls.py Tri a rejoint le salon 02:41 davin.baragiotta 31/08/2012 02:41:49 pas dans l'app annuaire... direct dans projet 31/08/2012 02:41:52 donc ça se lit comme suit : 31/08/2012 02:42:00 "voici un nouveau pattern d'URL : si après le nom de domain, ça commence avec (^) et finit ($) avec rien.... 31/08/2012 02:42:52 alors c'est la *fonction* dans carto_1_1.views.home qu'il faut exécuter 31/08/2012 02:43:17 et par ailleurs... le nom de ce pattern d'URL c'Est "home" 31/08/2012 02:43:30 voilà pour l'inteprétation de cette ligne 31/08/2012 02:43:38 maintenant... l'erreur devrait être différente au refresh 31/08/2012 02:43:49 shafeek.sumser 31/08/2012 02:43:55 oui davin.baragiotta 31/08/2012 02:44:09 il doit dire "hey.... j'ai pas de views correspondant" donc on va créer ce fichier views.py 31/08/2012 02:44:18 créez un fichier : carto_1_1/views.py 31/08/2012 02:44:32 PAS dans annuaire 31/08/2012 02:44:36 (fichier vide) 31/08/2012 02:44:47 petit mot sur génie logiciel... 31/08/2012 02:45:07 une app contient du code qui est logiquement peut dépendant du reste 31/08/2012 02:45:23 cohérence forte (dans l'app)... couplage faible (entre l'app et le reste) 31/08/2012 02:45:40 la page d'accueil... c'est la page du projet... 31/08/2012 02:45:49 pas de l'app... 31/08/2012 02:45:52 donc on la met ailleur que dans l'app 31/08/2012 02:45:59 donc on édite views.py : 31/08/2012 02:46:09 from django.shortcuts import render_to_response from django.template import Context, RequestContext def home(request): c = {} return render_to_response("home.html", Context(c), context_instance = RequestContext(request)) 31/08/2012 02:46:20 grrrrrrrrrr.... 31/08/2012 02:46:23 indenté 31/08/2012 02:46:28 # -*- encoding: utf-8 -*- from django.shortcuts import render_to_response from django.template import Context, RequestContext from carto_1_1.annuaire.models import Etablissement def home(request): """Page d'accueil du site""" c = { } return render_to_response("home.html", Context(c), context_instance = RequestContext(request)) 31/08/2012 02:46:43 copiez 31/08/2012 02:46:52 on en parle dans une seconde... 31/08/2012 02:46:57 ça c'est le code de base... qui se trouve dans la doc... 31/08/2012 02:47:20 c'est le bout pénible qu'on retient pas par coeur... 31/08/2012 02:47:29 et qu'on copie colle toujours 31/08/2012 02:47:34 aussi 31/08/2012 02:47:37 khone-cc 31/08/2012 02:47:38 Question de Khuon et Huy: (09:45:23) khuon.tiv: Could not import carto_1_1.views. Error was: No module named views davin.baragiotta 31/08/2012 02:47:55 khuon.tiv: justement... on crée ce views pour enelver l'erreur n'oubliez pas : 31/08/2012 02:48:12 le but d'une app web c'est de construire une réponse à la requête HTTP 31/08/2012 02:48:32 là notre requête c'est GET / 31/08/2012 02:48:39 c,est pas seulement urls.py qui fait la réponse 31/08/2012 02:48:51 urls.py a les règles pour dispatcher le travail 31/08/2012 02:49:01 ça dit "ah? tu veux /... alors le boulot doit se faire là :" 31/08/2012 02:49:13 le là en question.... on a dit que c'était dans views.py sur la racine du projet... 31/08/2012 02:49:31 Tri 31/08/2012 02:49:33 Davin, je demande a Khone de faire la moderation, je dois regler un pb de courriel au BAP davin.baragiotta 31/08/2012 02:49:40 ... mais il n'existe pas encore Tri ok 31/08/2012 02:49:42 donc on crée views.py à la racine. 31/08/2012 02:49:55 relisons le code qu'on vient de copier dans views... qu'on comprenne ce qu'on fait 31/08/2012 02:50:10 # -*- encoding: utf-8 -*- from django.shortcuts import render_to_response from django.template import Context, RequestContext from carto_1_1.annuaire.models import Etablissement def home(request): """Page d'accueil du site""" c = { } return render_to_response("home.html", Context(c), context_instance = RequestContext(request)) 31/08/2012 02:50:13 les imports... (from... import) 31/08/2012 02:50:22 c'est toujours pour utiliser ce qu'on importe plus bas 31/08/2012 02:50:30 on import donc render_to_responses et Context et RequestContext 31/08/2012 02:50:46 c'est utilisé plus bas 31/08/2012 02:50:50 idem pour Etablissement... 31/08/2012 02:50:57 def home() 31/08/2012 02:51:01 Tri a quitté la salle 02:51 davin.baragiotta 31/08/2012 02:51:09 def = fonction en Python tran.xuan.huy a quitté la salle 02:51 davin.baragiotta 31/08/2012 02:51:25 c'est la fonction qui a la responsabilité de créer la réponse à la requête HTTP home() prend en paramètre... jsutement la requête : request 31/08/2012 02:51:42 def home(request): 31/08/2012 02:51:50 Tri a rejoint le salon 02:52 davin.baragiotta 31/08/2012 02:52:18 une fonction peut retourner un résultat... ici, ce sera notre réponse Http return ... 31/08/2012 02:52:25 Tri a quitté la salle 02:52 davin.baragiotta 31/08/2012 02:53:07 render_to_response... son boulot et justement de faire le rendu d'un template (HTML)... pour construire la réponse finale à la requête Tri a rejoint le salon 02:53 tran.xuan.huy a rejoint le salon 02:53 davin.baragiotta 31/08/2012 02:53:34 si on regarde les param de render_to_response() "home.html"... c'est le template HTML qu'on veut "rendre".... c'est à dire interpréter et résoudre pour faire un rendu sous forme de réponse 31/08/2012 02:54:11 ritesh.dhora a rejoint le salon 02:54 davin.baragiotta 31/08/2012 02:54:34 Context et le RequestContext... c'est des variables qui sont passées au template on y revient 31/08/2012 02:54:42 bon! 31/08/2012 02:54:44 alors on a donc codé views.py : avec la focntion appelée par urls.py 31/08/2012 02:54:58 faites refresh... vous devriez avoir une dernière erreur 31/08/2012 02:55:10 des questions sur urls.py et views.py? 31/08/2012 02:55:19 khone-cc 31/08/2012 02:56:17 (09:56:50) Khone: Question: Dans le param de render_to_response(), on peut réponse plusieurs pages par home.html, contact.html ...? davin.baragiotta 31/08/2012 02:56:23 non khone-cc 31/08/2012 02:56:38 pas autre question, continue .. davin.baragiotta 31/08/2012 02:56:38 ça n'a pas de sens : on fait une réponse à une requête si tu veux "switcher"... soit du le fait dans l'urls.py (bonne approhce) 31/08/2012 02:56:54 ou tu switche plus haut dans la focntion.... 31/08/2012 02:57:03 mais chaque render_to_response() = 1 seul template 31/08/2012 02:57:13 maintenant votre erreur devrait plus être "hey on n'a pas de views" 31/08/2012 02:57:28 mais plutôt "hey, on n'a pas le template home.html!" 31/08/2012 02:57:40 donc on va le créer 31/08/2012 02:57:47 par convention 31/08/2012 02:57:57 dans les projets django 31/08/2012 02:58:01 on met les templates dans un répertoire nommé... 31/08/2012 02:58:10 templates! 31/08/2012 02:58:13 créez un répertoire templates à la racine du projet 31/08/2012 02:58:25 dans ce répertoire... créez home.html 31/08/2012 02:58:50 mettez quelque chose de sympa dans home.html 31/08/2012 02:59:18 genre :

J'aime Django

31/08/2012 02:59:35 en principe, un refresh devrait rendre le tout ok 31/08/2012 02:59:51 mais en principe seulement 31/08/2012 02:59:59 faut configurer Django pour qu'il sache où sont les templates 31/08/2012 03:00:11 lui dire la convention qu'on suit quoi! 31/08/2012 03:00:18 ouvrez settings.py 31/08/2012 03:00:32 onveut éditer TEMPLATE_DIRS 31/08/2012 03:00:43 lisez un peu le message en commentaire... 31/08/2012 03:00:51 khone-cc 31/08/2012 03:01:03 Question: (10:01:29) shafeek.sumser: faut modifier le settings.py pour activer le templates? davin.baragiotta 31/08/2012 03:01:23 oui essaie refresh sans avoir modifé settings.py 31/08/2012 03:01:33 toujours erreur, non? 31/08/2012 03:01:41 khone-cc 31/08/2012 03:01:56 Oui; tjs erreur .. davin.baragiotta 31/08/2012 03:01:59 bon l'idée... c'est que Django sache le path exact pour aller chercher les templates... 31/08/2012 03:02:21 bosco.boukone a rejoint le salon 03:02 davin.baragiotta 31/08/2012 03:02:39 absolute paths comment faire pour coder sans qu'on ait à modifer la config quand on déploiera sur serveur??? 31/08/2012 03:02:59 là on travaille dans notre home/user/... 31/08/2012 03:03:08 (ou ailleurs) 31/08/2012 03:03:12 mais on sait pas où code sera déployé sur serveur 31/08/2012 03:03:21 bref 31/08/2012 03:03:22 faut chemin absolu qu,on va construire dynamiquement : 31/08/2012 03:03:40 shafeek.sumser 31/08/2012 03:03:44 template_dirs à modifier aussi ? davin.baragiotta 31/08/2012 03:04:12 TEMPLATE_DIRS est à modifier... la seule config qu'on a tenté de modifié aujourd'hui (hier on a fait des modifs à settings) 31/08/2012 03:04:22 donc 31/08/2012 03:04:25 ajoutez : import os 31/08/2012 03:04:30 Tri a quitté la salle 03:04 davin.baragiotta 31/08/2012 03:04:33 en haut de fihier os = un module de standard library 31/08/2012 03:04:47 permet de manipuler le système de fichier 31/08/2012 03:04:54 ajouté ceci dans template dir : 31/08/2012 03:05:02 Tri a rejoint le salon 03:05 davin.baragiotta 31/08/2012 03:05:07 os.path.join(os.path.dirname(__file__), "templates"), ça donne ceci au final : 31/08/2012 03:05:13 TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "Cwww/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(os.path.dirname(__file__), "templates"), ) 31/08/2012 03:05:19 lisons.... 31/08/2012 03:05:22 __file__ = le fichier en cours... donc settings.py 31/08/2012 03:05:39 on dit donc "prend le répertoire parent de settings.py ey join le à "templates") 31/08/2012 03:06:07 khone-cc 31/08/2012 03:06:17 Question: (10:06:34) nguyen.le.duc.huy: Q: import os dans setting.py? davin.baragiotta 31/08/2012 03:06:32 pas le répertoire... en fait c'est le path absolu sur le système oui dans settings 31/08/2012 03:06:35 ça se résouds comme suit : /home/user/projets/carto_1_1/ 31/08/2012 03:07:00 pour moi 31/08/2012 03:07:03 c'est la façon de créer dynamiquement un path absolu vers un fichier... relativement à settings.py 31/08/2012 03:07:32 bref... si vous comprendez pas : pas grave, ça marche 31/08/2012 03:07:43 nguyen.le.duc.huy 31/08/2012 03:07:54 ls davin.baragiotta 31/08/2012 03:07:59 ? maintenant, ne faisant un refresh... 31/08/2012 03:08:08 vous devriez voir votre code HTML dans le navigateur ; 31/08/2012 03:08:25 plus d'erreur.... 31/08/2012 03:08:28 exact? 31/08/2012 03:08:39 ben bravo! vous avez une application web qui répond à une requête HTTP par une réponse HTTP : retourne du HTML 31/08/2012 03:09:45 31/08/2012 03:09:46 mmais bon... 31/08/2012 03:09:58 c'est pas très sexy comme traitement 31/08/2012 03:10:09 je vais vous montrer un peu l'intérêt d'un views.py 31/08/2012 03:10:21 on veut pas traiter juste des fihciers statiques... comme on vient de le faire avec notre home.html 31/08/2012 03:10:39 on veut du dynamique 31/08/2012 03:10:43 une page qui va afficher des variables 31/08/2012 03:10:55 31/08/2012 03:10:59 dans views.py 31/08/2012 03:11:05 focntion home 31/08/2012 03:11:08 on va "passer" une variable au template 31/08/2012 03:11:17 codez : dans le corps de la fcontion : 31/08/2012 03:11:57 def home(request): """Page d'accueil du site""" variable = "Davin" c = { 'var':variable, } return render_to_response("home.html", Context(c), context_instance = RequestContext(request)) 31/08/2012 03:12:39 lisons 31/08/2012 03:12:46 variable = 'Davin' 31/08/2012 03:12:52 c'est un string Python 31/08/2012 03:12:57 pas très dynamique car "hardcodé" dans la fonction 31/08/2012 03:13:10 codé en dur... 31/08/2012 03:13:13 (ensuite on va interroger la DB... on y arrive ) 31/08/2012 03:13:24 c = dictionnaire Python 31/08/2012 03:13:36 avec { } 31/08/2012 03:13:41 'var' = une des clés du dictionnaires (la seule déclarée) 31/08/2012 03:13:58 on voit que cette clé prend la valeur de variable 31/08/2012 03:14:11 'var':variable, 31/08/2012 03:14:17 finalement... 31/08/2012 03:14:22 le dictionnaire "c" est passé à Context 31/08/2012 03:14:39 qui a pour but de rendre accessible toutes les clés du dictionnaire 31/08/2012 03:14:56 comme des "variables" pour le template 31/08/2012 03:15:06 en clair : 'var' devient donc accessible dans le template 31/08/2012 03:15:17 faisons la preuve 31/08/2012 03:15:20 ouvrons le template 31/08/2012 03:15:23 édition : templates/home.html 31/08/2012 03:15:38 ajoutez un peu n'importe où "{{ var }}" 31/08/2012 03:15:57 la syntaxe dans un template... ce n'est plus du Python 31/08/2012 03:16:09 c'est un langage de template 31/08/2012 03:16:15 Django a son propre langage de template 31/08/2012 03:16:22 mais il existe des lanages indépendants dans l'univers Python, comme "mako" 31/08/2012 03:16:41 bref : Django est monolithique... il a ses propres trucs... et tout est documenté sur son site : pratique 31/08/2012 03:17:02 revenons à nos moutons 31/08/2012 03:17:08 donc le langage de template de Django nous permet d'afficher la valeur d'une variable passée au template : 31/08/2012 03:17:31 la syntexe c'est 31/08/2012 03:17:35 {{ nom_variable }} 31/08/2012 03:17:44 le nom de la variable, c'est la clé du dictionnaire... 31/08/2012 03:17:57 donc ici c'est {{ var }} 31/08/2012 03:18:05 refresh : vous devriez voir le string codé dans la fonction 31/08/2012 03:18:17 dans mon exemple : 'Davin' 31/08/2012 03:18:24 ça marche? 31/08/2012 03:18:27 des questions? 31/08/2012 03:18:30 on a un pépin avec un participant, on débogue dans tech 31/08/2012 03:22:30 thierry.tsitoara a quitté la salle 03:28 davin.baragiotta 31/08/2012 03:29:57 hourra! tout est réglé! 31/08/2012 03:30:00 on avait édité des fichiers sans les sauvegarder... et aussi 31/08/2012 03:30:12 on avait fait une erreur dans la clé du dictionnaire (nom de variable) 31/08/2012 03:30:34 bon 31/08/2012 03:30:35 maintenant passons aux choses sérieuses 31/08/2012 03:30:42 car afficher du code "hardcodé"... codé en dur... c'est nul 31/08/2012 03:30:56 on va interrogé la base de donnéess 31/08/2012 03:31:03 attachez-vous... là on va sérieusement devenir des développeurs d'applications web 31/08/2012 03:31:23 plan de match : 31/08/2012 03:31:31 https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support 31/08/2012 03:31:38 ORM : exploration interactive 31/08/2012 03:31:55 vous avez suivi l'atelier Python.... 31/08/2012 03:32:10 vous avez une idée de la puissance du langage et des imports qui viennent 31/08/2012 03:32:25 qui viennent avec 31/08/2012 03:32:38 dans Django 31/08/2012 03:32:49 le vrai code Python vit dans les views.py 31/08/2012 03:33:08 c'est à dire que le reste, c'est plutôt de la config 31/08/2012 03:33:19 bien sûr que urls.py c'est du Python 31/08/2012 03:33:27 mais on suit les convention de Django pour configurer nos patterns 31/08/2012 03:33:40 dans les views.py 31/08/2012 03:33:45 dans ses focntions on fait ce qu'on veut 31/08/2012 03:33:52 une page... son contenu... ça se construit comme on veut 31/08/2012 03:34:01 et cette consturction c'est dans views.py 31/08/2012 03:34:10 le rôle de views.py 31/08/2012 03:34:13 c'est de fournir les variables au template 31/08/2012 03:34:25 donc faire tout le traitement logique sur les données et "parler" à l'utilisateur dans le template 31/08/2012 03:34:44 notre projet... c,est celui d'un annuaire de l'AUF 31/08/2012 03:35:01 il est temps de coder autre chose que des hello world 31/08/2012 03:35:11 31/08/2012 03:35:12 on veut, dans nos views, appeler les données de la base de données 31/08/2012 03:35:33 les stocker dans des variables 31/08/2012 03:35:40 et les passer au template 31/08/2012 03:35:44 donc 31/08/2012 03:35:45 tout ceci se fait avec l'ORM de Django 31/08/2012 03:35:54 (il existe en Python d'autres ORM... comme SQLAlchemy, plus puissant d'ailleurs... mais on aime Django car il est monolithique) 31/08/2012 03:36:23 Django a son ORM 31/08/2012 03:36:30 la doc d'utilisation de l'ORM est ici : 31/08/2012 03:36:39 olivier.larcheveque a rejoint le salon 03:36 davin.baragiotta 31/08/2012 03:36:47 https://docs.djangoproject.com/en/1.4//topics/db/queries/ maintenant 31/08/2012 03:36:52 on va vu que la meilleure façon d'expérimenter en Python 31/08/2012 03:37:10 c'est dans l'interpréteur 31/08/2012 03:37:17 on va donc expérimenter l'ORM dans l'interpréteur 31/08/2012 03:37:32 pour lancer l'interpréteur avec tout l'environnement de Django 31/08/2012 03:37:48 (settings, par exemple) 31/08/2012 03:37:55 faut faire la commande suivante : 31/08/2012 03:38:02 python manage.py shell 31/08/2012 03:38:11 demandez à Django de lancez le shell dans le contexte de notre projet 31/08/2012 03:38:33 khone-cc 31/08/2012 03:38:37 (10:39:09) Khone: Question: est-ce qu'on peut utiliser: ipython manage.py shell ? davin.baragiotta 31/08/2012 03:38:42 non python = pour exécuter manage.py 31/08/2012 03:38:58 ensuite... manage.py exécute la commande shell 31/08/2012 03:39:09 et dans ce cas... il utilise ton shell préféré 31/08/2012 03:39:19 si tu as iPython d'installé 31/08/2012 03:39:26 c'est lui qui doit être lancé par : 31/08/2012 03:39:34 python manage.py shell 31/08/2012 03:39:40 exact? 31/08/2012 03:39:44 khone-cc 31/08/2012 03:39:48 ok davin.baragiotta 31/08/2012 03:39:59 ok super 31/08/2012 03:40:06 nous allons donc utilisez l'ORM 31/08/2012 03:40:15 dernier mot de théorie : 31/08/2012 03:40:21 ORM = object relational mapping 31/08/2012 03:40:29 c'est à dire 31/08/2012 03:40:31 association entre la notion d'objet et la notion de base de données relationnelle 31/08/2012 03:40:49 la DB relational = carto.db 31/08/2012 03:40:57 la notion d'objet = models.py 31/08/2012 03:41:04 olivier.larcheveque a quitté la salle 03:41 davin.baragiotta 31/08/2012 03:41:29 Django offre un lien automaitque... qui va nous permettre de faire en Python des requêtes sur la DB sans faire de SQL 31/08/2012 03:41:34 c'est tout l'idée derrière l'ORM 31/08/2012 03:41:41 utilisons-le 31/08/2012 03:41:47 from annuaire.models import * 31/08/2012 03:41:59 on importe dans le shell tous les modèles codés dans annuaire.models(.py) 31/08/2012 03:42:18 l'ORM existe sur nos classes déclarées dans models.py 31/08/2012 03:42:41 car on les a fait héritées de models.Model.... c'est lui, l'ORM! 31/08/2012 03:42:55 le modèle suprême! 31/08/2012 03:43:08 ok 31/08/2012 03:43:09 pour accéder aux objets (rows) de notre classe Etablissement... on a ce qu'on techniquement on appelle un manager : 31/08/2012 03:43:41 object 31/08/2012 03:43:43 Etablissement.objects 31/08/2012 03:43:50 c'est lui qui manage l'accès à la DB, disons.... 31/08/2012 03:44:01 on a ensuite des méthodes sur objects... qui font en Python ce qu,on veut faire en SQL : 31/08/2012 03:44:28 .all() = sélectionne tous les rows sans condition 31/08/2012 03:44:41 pas de WHERE SQL 31/08/2012 03:44:46 essayez : 31/08/2012 03:44:53 etablissements = Etablissement.objects.all() 31/08/2012 03:45:06 (on stocke les rows dans variable etablissements) 31/08/2012 03:45:16 ça marche? 31/08/2012 03:45:25 on peut introspecter, comme dans l,atelier Python! 31/08/2012 03:45:36 type(etablissements) 31/08/2012 03:45:42 on voit que c'est un QuerySet 31/08/2012 03:45:52 darasy.nong a quitté la salle 03:46 davin.baragiotta 31/08/2012 03:46:08 sous-entendu... un ensemble d'objets provenant d'une requête khone-cc 31/08/2012 03:46:15 Oui.. davin.baragiotta 31/08/2012 03:46:18 travaillons maintenant avec les données de la DB etablissements... c'est un conteneur de vos rows... sous forme d'objet Python!!!! 31/08/2012 03:46:43 (oubliez les fetch results!!!) 31/08/2012 03:46:52 maintenat, on sait qu'on peut itérer sur les conteneurs (comme les listes) 31/08/2012 03:47:11 en faisant un for! 31/08/2012 03:47:15 allez-y! 31/08/2012 03:47:18 for e in etablissement: print e 31/08/2012 03:47:27 31/08/2012 03:47:28 au pluriel, désolé 31/08/2012 03:47:36 for e in etablissements : print e 31/08/2012 03:47:46 ahaha 31/08/2012 03:47:47 ça affiche une représentation (__unicode__) des Etablissements! 31/08/2012 03:48:05 comme dans l,admin, en fait! 31/08/2012 03:48:13 bon... on va prendre qu'un établissement 31/08/2012 03:48:21 en utilisant les index : 31/08/2012 03:48:26 e = etablissements[0] 31/08/2012 03:48:35 ça marche? 31/08/2012 03:48:38 khone-cc 31/08/2012 03:48:46 moi, ouip davin.baragiotta 31/08/2012 03:48:49 des questions jusqu'à maintenant sur l'ORM? on continue 31/08/2012 03:49:08 e = un seul objet... c'est plus un itérable 31/08/2012 03:49:18 khone-cc 31/08/2012 03:49:35 (10:50:09) Khone: e = etablissements[0] rien afficher? davin.baragiotta 31/08/2012 03:49:38 on peut afficher son nom ou sigle... tous les champs déclarés dans models.py! non, c,est une assignation 31/08/2012 03:49:47 khone-cc 31/08/2012 03:49:54 (c le suivant qui affiche) davin.baragiotta 31/08/2012 03:50:09 on assigne dans la variable e l'indez 0 de etablissements juste e 31/08/2012 03:50:17 ou print e 31/08/2012 03:50:19 affiche le unicode de ce seul objet 31/08/2012 03:50:25 e.nom 31/08/2012 03:50:28 e.sigle 31/08/2012 03:50:30 c'est magnifique, non? 31/08/2012 03:50:37 bien sûr, pareil avec les personnes!!!! 31/08/2012 03:50:49 je vais vous montrer comment appeler un seul résultat (pas plusieurs) 31/08/2012 03:51:14 .get() 31/08/2012 03:51:16 Personne.objects.get(id=1) 31/08/2012 03:51:29 p = Personne.objects.get(id=1) 31/08/2012 03:51:38 khone-cc 31/08/2012 03:51:43 Question tran.xuan.huy: (10:49:54) tran.xuan.huy: je veux voir les sigle (10:49:58) tran.xuan.huy: comment on va faire davin.baragiotta 31/08/2012 03:51:45 (stockons le dans p, pour le manipuler e.sigle 31/08/2012 03:51:51 possible que e n'ait pas de data pour sigle... c,est un champs facultatifs 31/08/2012 03:52:10 tu veux voir tous les sigles de la DB? 31/08/2012 03:52:16 for e in etablissements: print e.sigle 31/08/2012 03:52:23 (la ligne print pourrait être en-dessous + indentée... obligé si plusieurs lignes de traitement) 31/08/2012 03:52:54 ok pour sigle? 31/08/2012 03:52:58 khone-cc 31/08/2012 03:53:00 (10:53:09) tran.xuan.huy: non, c'est ok pour moi davin.baragiotta 31/08/2012 03:53:03 p = qui? print p 31/08/2012 03:53:11 Davin? 31/08/2012 03:53:15 si oui... je sais que dans les datas (je les ai saisies) il a une date de naissance : 31/08/2012 03:53:30 p.date_naissance 31/08/2012 03:53:34 je veux vous montrer 2 autres trucs de l'ORM 31/08/2012 03:53:58 filter() 31/08/2012 03:54:03 pour faire un WHERE 31/08/2012 03:54:09 personnes = Personne.objects.filter(nom='Baragiotta') 31/08/2012 03:54:30 sort toutes les personnes avec ce nom compliqué 31/08/2012 03:54:38 (pas juste un) 31/08/2012 03:54:50 on peut même généralisé la recherche 31/08/2012 03:55:05 avec des commandes qu'on trouve dans le lien de la doc fourni plus haut : 31/08/2012 03:55:16 personnes = Personne.objects.filter(nom__startswith='Bara') 31/08/2012 03:55:30 explicite... 31/08/2012 03:55:35 la magie est dans le double underscore : __startswith 31/08/2012 03:55:46 aussi, finalement... 31/08/2012 03:55:54 tran.xuan.huy a quitté la salle 03:56 Tri a quitté la salle 03:56 davin.baragiotta 31/08/2012 03:56:17 le filter peut se faire sur un champ associé par une ForeignKey personnes = Personne.objects.filter(etablissement__nom__contains='Montréal') 31/08/2012 03:56:26 toutes les personnes qui ont ét.... 31/08/2012 03:56:36 ach 31/08/2012 03:56:37 dans le code c'est université 31/08/2012 03:56:42 : 31/08/2012 03:56:44 personnes = Personne.objects.filter(universite__nom__contains='Montréal') 31/08/2012 03:56:53 voilà 31/08/2012 03:56:56 toutes les personnes qui ont une université dont le nom contient "Montréal" 31/08/2012 03:57:16 31/08/2012 03:57:18 ça marche pour tous? 31/08/2012 03:57:27 khone-cc 31/08/2012 03:57:29 davin.baragiotta 31/08/2012 03:57:45 oubliez les reques complexes en SQL! *requêtes 31/08/2012 03:57:52 tran.xuan.huy a rejoint le salon 03:57 Tri a rejoint le salon 03:58 davin.baragiotta 31/08/2012 03:58:16 ok, pendant que je fais une pause santé... voici un exercice : le code que vous avez préféré, dans le shell... en explorant : 31/08/2012 03:58:31 copiez-le dans la fonction home() 31/08/2012 03:58:41 stockez l'infos que vous aimez dans les variables 31/08/2012 03:59:08 et passez les au template (à travers c = {} ) 31/08/2012 03:59:24 il faut au minimum la variable : 31/08/2012 03:59:40 etablissements = Etablissement.objects.all() 31/08/2012 03:59:45 svp 31/08/2012 03:59:47 (de retour dans 2 minutes) 31/08/2012 03:59:53 de retour 31/08/2012 04:02:07 davin.baragiotta a quitté la salle 04:08 davin.baragiotta a rejoint le salon 04:09 davin.baragiotta 31/08/2012 04:10:48 bon retombons sur nos pieds on faisait quoi? 31/08/2012 04:10:52 on explorait, dans le shell... l'utilisation de l'ORM pour appeler la DB en Python (pas en SQL) 31/08/2012 04:11:14 pour créer des variables dans home() 31/08/2012 04:11:25 donc 31/08/2012 04:11:29 on va maintenant coder le fruit de nos investigations : 31/08/2012 04:11:42 ajoutez dans home : 31/08/2012 04:12:27 etablissements = Etablissement.objects.all() c = { 'etablissements': etablissements, } 31/08/2012 04:12:42 ensuite, dans le template 31/08/2012 04:12:54 au lieu de faire {{ etablissements }} 31/08/2012 04:13:04 je vais vous montrer à boucler avec le langage de templating de Django 31/08/2012 04:13:19 ouvrez home.html 31/08/2012 04:13:27 il existe des "tags" 31/08/2012 04:13:36 qu'on peut utiliser dasn les templates 31/08/2012 04:13:43 voici la doc : 31/08/2012 04:13:48 https://docs.djangoproject.com/en/1.1/ 31/08/2012 04:14:13 1.1 31/08/2012 04:14:16 dans le centre y,a "Templage layer" 31/08/2012 04:14:27 template, désolé 31/08/2012 04:14:34 built-in tags and filters : 31/08/2012 04:14:48 https://docs.djangoproject.com/en/1.1/ref/templates/builtins/#ref-templates-builtins 31/08/2012 04:14:48 filters = un peu comme filtres SPIP 31/08/2012 04:14:59 tag = plus puissant 31/08/2012 04:15:06 tag for 31/08/2012 04:15:12 https://docs.djangoproject.com/en/1.1/ref/templates/builtins/#for 31/08/2012 04:15:22 {% for e in etablissements %} 31/08/2012 04:15:35 ça ressemble beaucoup à Python 31/08/2012 04:15:44 mais c'en est pas 31/08/2012 04:15:48 faut finir tout tag 31/08/2012 04:15:58 avec son endtag 31/08/2012 04:16:02 {% endfor %} 31/08/2012 04:16:08 codez ceci dans votre template, pour le plaisir : 31/08/2012 04:16:20 khone-cc 31/08/2012 04:17:31

Classe Etablisement

{% for e in etablissements %}
  • {{ e }}
  • {% endfor %} tran.xuan.huy a quitté la salle 04:17 davin.baragiotta 31/08/2012 04:17:39 ahaha oui! Tri a quitté la salle 04:17 davin.baragiotta 31/08/2012 04:17:53 (je fatigue! )

    Classe Etablisement

    {% for e in etablissements %}
  • {{ e }}
  • {% endfor %} 31/08/2012 04:18:02 mieux 31/08/2012 04:18:07 ajoutez 31/08/2012 04:18:21 avant et après for 31/08/2012 04:18:25 pour faire du vrai HTML 31/08/2012 04:18:30 khone-cc 31/08/2012 04:18:35 ok davin.baragiotta 31/08/2012 04:18:44 ok, vous voyez la liste des établissements? maintenant... malheureusement l,atelier tire à sa fin 31/08/2012 04:19:21 on est déja`en retard 31/08/2012 04:19:28 mais moi j'ai un peu de temps 31/08/2012 04:19:33 khone-cc 31/08/2012 04:19:37 moi, ça à l'aire bien affiché .. tran.xuan.huy a rejoint le salon 04:19 davin.baragiotta 31/08/2012 04:19:42 au mois pour conclure Tri a rejoint le salon 04:19 davin.baragiotta 31/08/2012 04:19:59 revenons au plan : ORM : utilisation réelle 31/08/2012 04:20:11 on est rendu dans l'utilisation réelle de l'ORM 31/08/2012 04:20:20 c'est fait 31/08/2012 04:20:22 rendez-vous compte des possibilités : 31/08/2012 04:20:31 vous appelez les données de la base de données comme vous voulez, pour créer une page HTML 31/08/2012 04:20:51 ça pourrait être du RSS 31/08/2012 04:20:58 appeller la DB pour lister dans un template respectant syntaxe RSS les nouvelles 31/08/2012 04:21:18 (mais y,a des outils qui font ça automatiquement) 31/08/2012 04:21:26 je voulais vous faire coder d'autres trucs 31/08/2012 04:21:40 mais tout est toujours trop long 31/08/2012 04:21:46 je vous propose donc de vous téléporter 31/08/2012 04:21:53 dans le temps 31/08/2012 04:21:55 en téléchargeant les sources finales de l'atelier 31/08/2012 04:22:03 avec plein truc dont je peux parler en démo 31/08/2012 04:22:13 (fini le code pour vous) 31/08/2012 04:22:18 ça vous va? 31/08/2012 04:22:21 https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support?action=AttachFile&do=get&target=carto_1_1_final.tar.gz 31/08/2012 04:22:41 sources finales 31/08/2012 04:22:48 décompresser + aller dans répertoire 31/08/2012 04:23:05 + python manage.py runserver 31/08/2012 04:23:12 tout le monde y est? 31/08/2012 04:24:19 Tri a quitté la salle 04:28 tran.xuan.huy a quitté la salle 04:28 Tri a rejoint le salon 04:30 Tri a quitté la salle 04:30 Tri a rejoint le salon 04:31 tran.xuan.huy a rejoint le salon 04:31 davin.baragiotta 31/08/2012 04:33:08 messieurs... l'heure est grave.... c'est la finale en feu d'artifice 31/08/2012 04:33:18 vous avez téléchargé les sources finales 31/08/2012 04:33:28 vous avez décompressé le .tar.gz 31/08/2012 04:33:40 vous êtes dans le répertoire du projet décompressé 31/08/2012 04:33:54 vous allumez le feu : python manage.py runserver 31/08/2012 04:34:04 et allez sur : 31/08/2012 04:34:08 http://127.0.0.1:8000 31/08/2012 04:34:18 tadaaaaaaaaaaaaaaaaaaaaaaaaaam!!!!!! 31/08/2012 04:34:23 vous devriez avoir un super site avec des styles 31/08/2012 04:35:08 entre autres 31/08/2012 04:35:12 ça marche? (mais cachez votre joie!) 31/08/2012 04:35:23 tran.xuan.huy a quitté la salle 04:35 Tri a quitté la salle 04:35 davin.baragiotta 31/08/2012 04:36:55 bon je termine en vous montrant ce qui a été fait... que vous n'avez pas fait : https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support 31/08/2012 04:37:04 héritage de template 31/08/2012 04:37:09 regardez bien... y,a un base.html 31/08/2012 04:37:17 qui déclare des {% block ... 31/08/2012 04:37:26 et toutes les autres pages 31/08/2012 04:37:33 {% extends "base.html" 31/08/2012 04:37:43 de sorte que tout le vrai code HTML qu'on veut pas coder dans chaque page 31/08/2012 04:37:57 est dans base.html 31/08/2012 04:38:01 et les autres pages remplissent les block 31/08/2012 04:38:10 autre chose 31/08/2012 04:38:14 les URLs avec paramètres 31/08/2012 04:38:24 ouvres annuaire/urls.py 31/08/2012 04:38:32 voyez la syntaxe particulière pour capter l'id 31/08/2012 04:38:43 ouvrez annuaire/views.py 31/08/2012 04:38:56 regardez le id passé à la fonction... qui nous permet de faire un .get() dans l'ORM... comme on a fait dans le shell 31/08/2012 04:39:25 avec ça : on fait une page de détail... pour CET établissement ou CETTE personne 31/08/2012 04:39:43 le plus impressionnant, c'est le style 31/08/2012 04:40:03 mais c'est rien d'autre que du CSS 31/08/2012 04:40:11 dans répertoire /media/ 31/08/2012 04:40:19 correctemetn configuré dans settings.py 31/08/2012 04:40:27 et utilisé dans base.html : {{ MEDIA_URL }} 31/08/2012 04:40:41 finalement... 31/08/2012 04:40:55 la connexion du user 31/08/2012 04:40:59 que je vous laisse expérimenter dans les interfaces 31/08/2012 04:41:11 et étudier sur : urls.py, connexion.html, deconnexion.html 31/08/2012 04:41:26 shafeek.sumser a quitté la salle 04:41 davin.baragiotta 31/08/2012 04:41:35 voilà, c'est tout? (24 minutes de dépassé) 31/08/2012 04:41:53 des questions? 31/08/2012 04:41:55 nguyen.le.duc.huy 31/08/2012 04:42:46 ls davin.baragiotta 31/08/2012 04:42:54 si pas de question... je conclue ls = ? 31/08/2012 04:42:58 nguyen.le.duc.huy 31/08/2012 04:42:58 Pardon trompe la fenentre davin.baragiotta 31/08/2012 04:43:02 ah! khone-cc 31/08/2012 04:43:32 (11:43:37) khuon.tiv: Combien de web codes ont dans cet interface ? Python-Django CSS HTML quoi d'autre ? davin.baragiotta 31/08/2012 04:44:38 web codes? pas sûr de comprendre... mais les technos impliqués : oui : python, django (framework Python), Apache éventuellement, HTTP, CSS, HTML, JS au besoin 31/08/2012 04:45:04 voir le schéma : 31/08/2012 04:45:07 http://montrealpython.org/r/attachments/13/web-development.jpg 31/08/2012 04:45:15 shafeek.sumser a rejoint le salon 04:45 davin.baragiotta 31/08/2012 04:45:25 autres questions? khone-cc 31/08/2012 04:45:40 Non yeap, GRAND MERCI PROF PYTHON-DJANGO... 31/08/2012 04:45:43 davin.baragiotta 31/08/2012 04:45:59 khone-cc 31/08/2012 04:46:01 on lui laisse à Dodo... davin.baragiotta 31/08/2012 04:46:05 je conclue donc rapido : vous avex une bombe entre les mains : 31/08/2012 04:46:13 la puissance de Python sur le web 31/08/2012 04:46:19 tout ce que vous êtes capables de faire avec des import de Python... 31/08/2012 04:46:37 ... vous pouvez l'utiliser sur le web avec les views... 31/08/2012 04:46:49 et stocker vos data dans une DB 31/08/2012 04:46:57 (là c'était sqlite... mais on peut mettre MySQL évidemment, ou autre) 31/08/2012 04:47:20 tous nos projets SI de l'AUF = Django 31/08/2012 04:47:32 y,a du Python partant dans git.auf.org! 31/08/2012 04:47:41 je vous laisse apprécier la montée en puissance que vous venez de faire 31/08/2012 04:47:57 et surtout 31/08/2012 04:47:58 on est tous ensemble, tout le temps... la communauté tech : 31/08/2012 04:48:10 on vit dans le salon tech, ari-si ou autres 31/08/2012 04:48:18 shafeek.sumser 31/08/2012 04:48:29 davin une dernière question: est-ce qu'avec django on peut faire du ajax et jquery? davin.baragiotta 31/08/2012 04:48:30 n'hésitez à poser les questions et... ... on n'est pas obligés d,attendre la prochaine semaine Tech pour continuer d'apprendre et collaborer 31/08/2012 04:48:55 réponse : 31/08/2012 04:48:59 oui, Ajax = rien d'autre qu'un appel de JS sur serveur... 31/08/2012 04:49:15 un appel partiel, en quelque sorte car veut pas une page complète 31/08/2012 04:49:36 donc 31/08/2012 04:49:37 on met le code JQuery qu'on veut dans notre template HTML 31/08/2012 04:49:52 dans une balise link qui lie vers un script : dans /media/js ( {{ MEDIA_URL }}/js/le_script_qui_tue.js 31/08/2012 04:50:35 ensuite 31/08/2012 04:50:41 ce script appelle une URL 31/08/2012 04:50:47 gérée dans urls.py 31/08/2012 04:50:51 qui appelle une fonction dans views.py 31/08/2012 04:51:01 qui retourne un FRAGMENT HTML 31/08/2012 04:51:10 même principe qu'on vient de voir 31/08/2012 04:51:18 sauf un appel partiel pour raffraichir un fragmenr de code 31/08/2012 04:51:30 le JS dans jQuery qui reçoit la réponse partielle... 31/08/2012 04:51:47 ... va ajouter ce fragment dans le DOM en cours 31/08/2012 04:51:57 shafeek.sumser 31/08/2012 04:52:00 ok j'étais pas présent, viens d'arriver au bureau je rattraperai ce soir davin.baragiotta 31/08/2012 04:52:03 voilà ok à ce soir (ce matin pour moi... en fait ) 31/08/2012 04:52:18 }}} ---------------------- FIN ATELIER DJANGO FRONTEND -------------------------------- 31/08/2012 04:52:35