Modifications entre les versions 1 et 16 (s'étendant sur 15 versions)
Version 1 à la date du 2011-12-12 04:38:25
Taille: 7454
Éditeur: DavinBaragiotta
Commentaire: Premier jet : format wiki redmine, contenu Montréal-Python
Version 16 à la date du 2011-12-12 08:16:05
Taille: 6567
Éditeur: DavinBaragiotta
Commentaire: sources
Texte supprimé. Texte ajouté.
Ligne 1: Ligne 1:
h1. Plan détaillé

h2.
INTRODUCTION

* Présentations
** Davin Baragiotta
** Montréal-Python (MP, sprints/hackathons, ateliers, PyCon)
* Objectifs
** connaître l'architecture d'un projet : principaux fichiers
** gérer data dans backend
** présenter data dans frontend
*
Documentation
*
* doc : bonne version de django
*** officielle : https://docs.djangoproject.com/en/1.3/
*** français : http://docs.django-fr.org/
** tutoriel
**
* Part 1 : créer un projet, créer une app, jouer avec ORM (API) _couvert ici_
*** Part
2 : backend (admin) _couvert ici_
**
* Part 3 : frontend _couvert ici, plus straightforward même ;)_
**
* Part 4 : forms et vues génériques _pas couvert ici_
* Environnement technique
** Python >= 2.5
** Django 1.3.1
*** Mac OS X : voir tutoriel Part 1 pour manip supplémentaire

h2. PARTIE 1 : DÉVELOPPEMENT WEB AVEC DJANGO : ARCHITECTURE D'UN PROJET

h3. Développement web

* schéma : le développement web
** rôle d'un framework web : aider à construire réponse à une requête
* développement (DEV)
* déploiement (PROD, TEST)

h3. Django

Pourquoi django vs autre framework
* all-in-one
* admin : meilleur vendeur ;)
* docs
* communauté : utilisation répandue
= Atelier 2011-12-12 : Plan détaillé =

==
INTRODUCTION ==

 
* Objectifs
  * connaître l'architecture d'un projet : principaux fichiers
  * présenter des données dans le frontend (interface publique) avec Django
 * Documentation
  
* doc : bonne version de django
   * officielle : https://docs.djangoproject.com/en/1.1/
   * français : http://docs.django-fr.org/
   * AUF : page wikiteki sur [[Django]]
  * tutoriel
   
* Part 1 : créer un projet, créer une app, jouer avec ORM (API) ''couvert en partie lors de atelier 2011-12-07''
   * Part 2
: backend (admin) ''couvert lors de atelier 2011-12-07''
   
* Part 3 : frontend ''couvert ici, plus efficacement même ;)''
   
* Part 4 : forms et vues génériques ''pas couvert ici''
 
* Environnement technique
  * Python >= 2.5
  * Django 1.1.1
   * Mac OS X : voir tutoriel Part 1 pour manip supplémentaire

== PARTIE 1 : RAPPELS ==

===
Django ===
Ligne 44: Ligne 28:
* models.py
* admin.py
* urls.py
* views.py
* templates (HTML)

h3. Projet : définition du besoin

Montréal-Python a une ligue de hockey cosom _(ce n'est pas vrai)_.
On veut gérer quels joueurs sont dans quelles équipes...
... et planifier les matchs de la saison.

h3. Projet : modélisation

* Joueur
* Equipe
* Match

h2. PARTIE 2 : HANDS-ON : PROJET ET APPLICATIONS

h3. Création du projet

<pre>
django-admin.py startproject liguemp
cd liguemp
</pre>

* survol des fichiers générés

<pre>
python manage.py runserver
</pre>

* settings.py
** DATABASE_*

h3. Création d'une application

<pre>
python manage.py startapp recrutement
</pre>

* survol fichiers

* recrutement/models.py
** documentation :
https://docs.djangoproject.com/en/1.3/topics/db/models/
https://docs.djangoproject.com/en/1.3/ref/models/fields/
** yeah! on code!
*** Joueur.nom
*** Equipe.nom

* settings.py
** INSTALLED_APP
*** 'recrutement'

<pre>
python manage.py syncdb
</pre>

h3. Backend : gérer les données dans l'admin

* urls.py
_activer admin : décommenter_
** import
** autodiscover
** url : admin/

* http://127.0.0.1:8000/

* settings.py
** INSTALLED_APP
*** 'django.contrib.admin'

* recrutement/admin.py
_enregistrer modèles
voir tutoriel Part 2_
https://docs.djangoproject.com/en/1.3/intro/tutorial02/

* http://127.0.0.1:8000/admin/

* recrutement/models.py
<pre>def __unicode__(self):</pre>
** Joueur.prenom

* delete liguemp.db

<pre>
python manage.py syncdb
</pre>

> fixtures
> https://docs.djangoproject.com/en/1.3/ref/django-admin/
>
> south
> http://south.aeracode.org/

* recrutement/models.py
** Joueur.equipe

h3. Frontend : présenter les données

* recrutement/urls.py
https://docs.djangoproject.com/en/1.3/topics/http/urls/
** home

* recrutement/views.py
https://docs.djangoproject.com/en/1.3/topics/http/views/
_voir tutoriel Part 3 (version shortcut)_
https://docs.djangoproject.com/en/1.3/intro/tutorial03/

* templates
https://docs.djangoproject.com/en/1.3/topics/templates/
** créer répertoire templates
** settings.py
<pre>
os.path.join(os.path.dirname(__file__), "templates"),
 * models.py
 * admin.py
 * urls.py
 * views.py
 * templates (HTML)

=== Projet carto : définition du besoin ===

L'AUF veut procéder à la cartographie de ses établissements membres.

On veut savoir quelle formation est donnée où...

... et répertorier les projets des membres.

=== Projet carto : modélisation ===

 * Etablissement
 * Formation
 * Projet

== PARTIE 2 : HANDS-ON : PROJET ET APPLICATIONS ==

=== Repartir des sources initiales ===

Repartir du projet créé lors de l'atelier du 2011-12-07 : sources initiales [[attachment:sources.tar.gz]]

Nous avions alors :
 * Créé le projet carto
 * Créé l'application etablissements
 * Créé les modèles Etablissement et Formation
 * Géré dans l'admin des Etablissements et des Formations

=== Frontend : présenter les données ===

 * urls.py
 https://docs.djangoproject.com/en/1.1/topics/http/urls/
  * home

 * views.py
 https://docs.djangoproject.com/en/1.1/topics/http/views/

 ''voir tutoriel Part 3 (version shortcut)''

 https://docs.djangoproject.com/en/1.1/intro/tutorial03/

 * templates
 https://docs.djangoproject.com/en/1.1/topics/templates/
  * créer répertoire templates
  * settings.py
  {{{
Ligne 162: Ligne 79:
</pre>
** templates/recrutement/home.html

* recrutement/views.py
_passer une variable au template_

* templates/recrutement/home.html
_utiliser une variable :_
<pre>
TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/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"),
)
}}}
  * templates/home.html

 * views.py
 ''passer une variable au template''

 * templates/home.html
 ''utiliser une variable :''
 {{{
Ligne 172: Ligne 95:
</pre>

* recrutement/views.py
_endroit où on code en logique en Python
plus simple si explore interactivement..._

<pre>
}}}

 * views.py
 ''endroit où on code la logique en Python...''

 ''...
plus simple si explore interactivement''

 {{{
Ligne 180: Ligne 104:
</pre>

* ORM (API) : object relation mapping
<pre>
from recrutement
.models import *
equipes = Equipe.objects.all()
for e in equipe
s: print e
e = equipes[0]
e.joueur_set.all()
j = Joueur.objects.get(id=1)
j.id
j = Joueur
.objects.get(id=314)
}}}

 
* ORM (API) : object relationnal mapping
 {{{
from etablissements
.models import *
etablissements = Etablissement.objects.all()
for e in etablissement
s: print e
e = etablissements[0]
e.formation_set.all()
f = Formation.objects.get(id=1)
f.id
f = Formation
.objects.get(id=314)
Ligne 193: Ligne 117:
joueurs = Joueur.objects.filter(equipe__nom__startswith='Pyth')
</pre>

* recrutement/models.py
<pre>
related_name = "joueurs"
</pre>

* relancer shell
<pre>
e.joueurs.all()
e.joueurs.count()
</pre>

* recrutement/views.py
_passer les variables pertinentes pour accueil_

* templates/recrutement/home.html
_boucle for dans template :_
<pre>
{% for e in equipes %}
formations = Formation.objects.filter(etablissement__nom__contains='Hanoi')
}}}

 * etablissements/models.py
 {{{
related_name = "formations"
}}}

 * relancer shell
 {{{
e.formations.all()
e.formations.count()
}}}

 * views.py
 ''passer les variables pertinentes pour accueil''

 * templates/home.html
 ''boucle for dans template :''
 {{{
{% for e in etablissements %}
Ligne 215: Ligne 139:
</pre>

h2. PARTIE 3 : PROJET LIGUEMP PIMPÉ

Télécharger les sources du projet pimpé :
http://m
ontrealpython.org/r/attachments/8

Extraire (_sans clash de nom avec projet en c
ours_)
}}}

== PARTIE 3 : PROJET CARTO PIMPÉ ==

Télécharger les sources finales du projet pimpé : sources finales [[attachment:sources.tar.gz]]
Ligne 226: Ligne 147:
h3. Héritage de templates

* base.html
<pre>
=== Héritage de templates ===

 * base.html
 {{{
Ligne 231: Ligne 152:
</pre>

* templates
<pre>
}}}

 * templates
 {{{
Ligne 237: Ligne 158:
</pre>

h3. Fichiers statiques : CSS, images et js

https://docs.djangoproject.com/en/1.3/howto/static-files/

* répertoire : static
** css
** images
** js

* settings.py
** STATICFILES_DIRS
<pre>
os.path.join(os.path.dirname(__file__), "static"),
</pre>

* urls.py
<pre>
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
</pre>

h3. Connexion du user

* templates
** connexion.html
** deconnexion.html

* urls.py
** connexion
** deconnexion

* settings.py
<pre>
}}}

=== Fichiers statiques : CSS, images et js ===

https://docs.djangoproject.com/en/1.1/howto/static-files/

 * répertoire : static
  * css
  * images
  * js

 * settings.py
 {{{
MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media')
MEDIA_URL = '/static/'
}}}

 * urls.py
 {{{
from django.conf import settings
if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^static/(?P<path>.*)$', 'django.views.static.serve',
         {'document_root': settings.MEDIA_ROOT}),
    )
}}}

=== Connexion du user ===

 * templates
  * connexion.html
  * deconnexion.html

 * urls.py
  * connexion
  * deconnexion

 * settings.py
 {{{
Ligne 273: Ligne 198:
</pre>

h3.
URL avec paramètres

* pages de détail : capter l'id de l'objet
** urls.py : import des urls de l'app recrutement
** recrutement
/urls.py
** recrutement/views.py
** templates/recrutement/*

h3. Refactoring du home

* urls home dans views.py à la racine

h3. Admin pimpé : ModelAdmin

* recrutement/admin.py

* classes Joueur
Admin, EquipeAdmin
_
héritent de ModelAdmin_
*
* enregistrer Modele avec ModeleAdmin
<pre>
admin.site.register(Joueur, JoueurAdmin)
</pre>
*
* config ModeleAdmin
<pre>
}}}

===
URL avec paramètres ===

 
* pages de détail : capter l'id de l'objet
  * urls.py : import des urls de l'app etablissements
  * etablissements
/urls.py
  * etablissements/views.py
  * templates/etablissements/*

=== Admin pimpé : ModelAdmin ===

 * etablissements/admin.py

 *
classes EtablissementAdmin, FormationAdmin

 ''
héritent de ModelAdmin''

  
* enregistrer Modele avec ModeleAdmin
  {{{
admin.site.register(Formation, FormationAdmin)
}}}
  
* config ModeleAdmin
  {{{
Ligne 302: Ligne 225:
</pre>
*
* plus?
https://docs.djangoproject.com/en/1.3/ref/contrib/admin/
*** fields
*** fieldsets

h3.
Charger données initiales : fixtures

https://docs.djangoproject.com/en/1.3/ref/django-admin/

* créer répertoire fixtures à la racine

<pre>
}}}
  
* plus? https://docs.djangoproject.com/en/1.1/ref/contrib/admin/
   * fields
   * fieldsets

===
Charger données initiales : fixtures ===

https://docs.djangoproject.com/en/1.1/ref/django-admin/

 * créer répertoire fixtures à la racine
 {{{
Ligne 316: Ligne 237:
</pre>

* mettre initial_data.json dans fixtures

* pour récupération data :
<pre>
}}}

 * mettre initial_data.json dans fixtures

 * pour récupération data :
 {{{
Ligne 325: Ligne 246:
</pre>

h2.
PARTIE 4 : HANDS-ON : CRÉER L'APPLICATION SAISON POUR LE PROJET LIGUEMP

h3.
Ajouter modèle Match

* Match
** date
** lieu
** equipe1
** equipe2
** score1
** score2

h3.
Autre exercice : age d'un joueur

* Joueur.date_naissance
* Joueur.ag
e()
_ajouter une methode age() sur la classe Joueur utilisant la date de naissance_

h2.
CONCLUSION : POUR CONTINUER

* Autres aspects non couverts (quelques uns)
** permissions et décorateurs
** manage.py inspectdb
** manage.py test
** forms
** generic views
** templates : tags, filtres

* Mailing list Django users :
http://groups.google.com/group/django-users

* Channel IRC #django :
irc://irc.freenode.net/django

* Contribs, plugins
https://docs.djangoproject.com/en/dev/ref/contrib/
** south
** reversion
** Autre : pypi
http://pypi.python.org/

* Enjoy!

h2. SONDAGE DE SATISFACTION

* http://www.surveymonkey.com/s/XKP2NP7
}}}

==
PARTIE 4 : HANDS-ON : CRÉER L'APPLICATION PROJET POUR LE PROJET CARTO ==

=== A
jouter modèle Projet ===

 * Projet
  * nom
  * date_debut
  * date_fin
  * etablissements

===
Autre exercice : durée d'un Projet et avancement d'un Projet ===

 * Projet.dure
e()
 {{{
"""Durée prévue en fonction des dates de début et de fin"""
}}}
 * Projet.avancement
()
 {{{
"""Durée réelle à partir de la date de début jusqu'à maintenant."""
}}}

==
CONCLUSION : POUR CONTINUER ==

 
* Autres aspects non couverts (quelques uns)
  * permissions et décorateurs
  * manage.py inspectdb
  * manage.py test
  * forms
  * generic views
  * templates : tags, filtres

 * Mailing list Django users :
 http://groups.google.com/group/django-users

 * Channel IRC #django :
 irc://irc.freenode.net/django

 * Contribs, plugins
 https://docs.djangoproject.com/en/dev/ref/contrib/
  * south
  * reversion
  * Autre : pypi
 http://pypi.python.org/

 * Enjoy!

Atelier 2011-12-12 : Plan détaillé

INTRODUCTION

  • Objectifs
    • connaître l'architecture d'un projet : principaux fichiers
    • présenter des données dans le frontend (interface publique) avec Django
  • Documentation
    • doc : bonne version de django
    • tutoriel
      • Part 1 : créer un projet, créer une app, jouer avec ORM (API) couvert en partie lors de atelier 2011-12-07

      • Part 2 : backend (admin) couvert lors de atelier 2011-12-07

      • Part 3 : frontend couvert ici, plus efficacement même ;)

      • Part 4 : forms et vues génériques pas couvert ici

  • Environnement technique
    • Python >= 2.5

    • Django 1.1.1
      • Mac OS X : voir tutoriel Part 1 pour manip supplémentaire

PARTIE 1 : RAPPELS

Django

Principaux fichiers

  • models.py
  • admin.py
  • urls.py
  • views.py
  • templates (HTML)

Projet carto : définition du besoin

L'AUF veut procéder à la cartographie de ses établissements membres.

On veut savoir quelle formation est donnée où...

... et répertorier les projets des membres.

Projet carto : modélisation

  • Etablissement
  • Formation
  • Projet

PARTIE 2 : HANDS-ON : PROJET ET APPLICATIONS

Repartir des sources initiales

Repartir du projet créé lors de l'atelier du 2011-12-07 : sources initiales sources.tar.gz

Nous avions alors :

  • Créé le projet carto
  • Créé l'application etablissements
  • Créé les modèles Etablissement et Formation
  • Géré dans l'admin des Etablissements et des Formations

Frontend : présenter les données

  • urls.py

    https://docs.djangoproject.com/en/1.1/topics/http/urls/

    • home
  • views.py

    https://docs.djangoproject.com/en/1.1/topics/http/views/

    voir tutoriel Part 3 (version shortcut)

    https://docs.djangoproject.com/en/1.1/intro/tutorial03/

  • templates

    https://docs.djangoproject.com/en/1.1/topics/templates/

    • créer répertoire templates
    • settings.py
      import os
      TEMPLATE_DIRS = (
          # Put strings here, like "/home/html/django_templates" or "C:/www/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"),
      )
    • templates/home.html
  • views.py

    passer une variable au template

  • templates/home.html

    utiliser une variable :

    {{ var }}
  • views.py

    endroit où on code la logique en Python...

    ...plus simple si explore interactivement

    python manage.py shell
  • ORM (API) : object relationnal mapping
    from etablissements.models import *
    etablissements = Etablissement.objects.all()
    for e in etablissements: print e
    e = etablissements[0]
    e.formation_set.all()
    f = Formation.objects.get(id=1)
    f.id
    f = Formation.objects.get(id=314)
    e.id
    formations = Formation.objects.filter(etablissement__nom__contains='Hanoi')
  • etablissements/models.py
    related_name = "formations"
  • relancer shell
    e.formations.all()
    e.formations.count()
  • views.py

    passer les variables pertinentes pour accueil

  • templates/home.html

    boucle for dans template :

    {% for e in etablissements %}
    {% endfor %}

PARTIE 3 : PROJET CARTO PIMPÉ

Télécharger les sources finales du projet pimpé : sources finales sources.tar.gz

Pimpé? Quoi de neuf?

Héritage de templates

  • base.html
    {% block main %}
  • templates
    {% extends "base.html" %}
    {% block main %}

Fichiers statiques : CSS, images et js

https://docs.djangoproject.com/en/1.1/howto/static-files/

  • répertoire : static
    • css
    • images
    • js
  • settings.py
    MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media')
    MEDIA_URL = '/static/'
  • urls.py
    from django.conf import settings
    if settings.DEBUG:
        urlpatterns += patterns('',
            (r'^static/(?P<path>.*)$', 'django.views.static.serve',
             {'document_root': settings.MEDIA_ROOT}),
        )

Connexion du user

  • templates
    • connexion.html
    • deconnexion.html
  • urls.py
    • connexion
    • deconnexion
  • settings.py
    LOGIN_REDIRECT_URL = "/"

URL avec paramètres

  • pages de détail : capter l'id de l'objet
    • urls.py : import des urls de l'app etablissements
    • etablissements/urls.py
    • etablissements/views.py
    • templates/etablissements/*

Admin pimpé : ModelAdmin

Charger données initiales : fixtures

https://docs.djangoproject.com/en/1.1/ref/django-admin/

  • créer répertoire fixtures à la racine
    python manage.py dumpdata > initial_data.json
  • mettre initial_data.json dans fixtures
  • pour récupération data :
    python manage.py syncdb
    no (pas créer user)
    python manage.py loaddata fixtures/initial_data.json

PARTIE 4 : HANDS-ON : CRÉER L'APPLICATION PROJET POUR LE PROJET CARTO

Ajouter modèle Projet

  • Projet
    • nom
    • date_debut
    • date_fin
    • etablissements

Autre exercice : durée d'un Projet et avancement d'un Projet

  • Projet.duree()
    """Durée prévue en fonction des dates de début et de fin"""
  • Projet.avancement()
    """Durée réelle à partir de la date de début jusqu'à maintenant."""

CONCLUSION : POUR CONTINUER

Ateliers/2011-12-12/PlanDetail (dernière édition le 2011-12-12 08:16:05 par DavinBaragiotta)