Taille: 6291
Commentaire:
|
← Version 35 à la date du 2012-08-31 16:43:35 ⇥
Taille: 10218
Commentaire:
|
Texte supprimé. | Texte ajouté. |
Ligne 2: | Ligne 2: |
= Frontend : interfaces publiques d'un site = <<TableOfContents(3)>> |
= Django : Frontend : interfaces publiques d'un site = <<TableOfContents(4)>> |
Ligne 11: | Ligne 11: |
* connaître l'architecture d'un projet : principaux fichiers * gérer data dans backend * présenter data dans frontend |
* présenter des données dans le frontend (interface publique) avec Django |
Ligne 16: | Ligne 14: |
* officielle : https://docs.djangoproject.com/en/1.3/ | * officielle : [[https://docs.djangoproject.com/en/1.4/|Django 1.4]], [[https://docs.djangoproject.com/en/1.1/|Django 1.1]] |
Ligne 19: | Ligne 17: |
* 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 1 : créer un projet, créer une app, jouer avec ORM (API) '''couvert ici''' * Part 2 : backend (admin) ''pas couvert ici (voir atelier [[Ateliers/Django/Backend|Backend]])'' * Part 3 : frontend '''couvert ici, plus directement même ;)''' |
Ligne 25: | Ligne 23: |
* Django 1.3.1 | * Django 1.1.1 ou 1.4 * South 0.6 ou 0.7.4 (optionnel, recommandé) * Vérification des versions : {{{ >>> import django >>> django.get_version() '1.4' >>> import south >>> south.__version__ '0.7.4.' }}} * Django : version recommandée à l'AUF * la version qui vient avec debian sur les serveurs de production * sauf si vous êtes prêt à assurer une maintenance manuelle de Django |
Ligne 29: | Ligne 40: |
== PARTIE 1 : RAPPELS == * Django * Projet carto : définition du besoin * Projet carto : modélisation |
== PARTIE 1 : RAPPELS ET AMORCE DU PROJET == === Rappels === ''Ces rappels couvrent les parties 1 et 2 de l'[[Ateliers/Django/Backend/Support|atelier Backend]]'' * Développement web : schéma sur le [[http://montrealpython.org/r/attachments/13/web-development.jpg|développement web]] * Django : les principaux fichiers dans l'architecture d'un projet * Projet carto : définition du besoin et modélisation === Amorce du projet === 1. Prendre ces sources avec jeu de données ('''recommandé'''): ''superuser = admin/admin'' * Projet carto : Django 1.4 * Projet carto : [[Ateliers/Django/Frontend/Support?action=AttachFile&do=get&target=carto_1_1_backend_final.tar.gz|Django 1.1.1]] 1. ou repartir de votre code du projet carto de l'[[Ateliers/Django/Backend/Support|atelier Backend]] si vous l'avez suivi avant 1. ou partir à zéro en codant le projet : {{{ django-admin.py startproject carto }}} Django 1.1.1 : {{{ django-admin startproject carto }}} {{{ cd carto python manage.py startapp annuaire }}} * coder les modèles de l'app annuaire : annuaire/models.py : {{{ from django.db import models class Etablissement(models.Model): nom = models.CharField(max_length=255) sigle = models.CharField(max_length=50) def __unicode__(self): return self.nom class Personne(models.Model): nom = models.CharField(max_length=255) prenom = models.CharField(max_length=255, blank=True, null=True) date_naissance = models.DateField(blank=True, null=True) universite = models.ForeignKey('Etablissement', blank=True, null=True) def __unicode__(self): return "%s %s" % (self.nom.upper(), self.prenom) }}} * activer l'admin dans urls.py : {{{ # ... from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # ... url(r'^admin/', include(admin.site.urls)), ) }}} * associer les modèles de l'app annuaire à l'admin : créer annuaire/admin.py : {{{ from django.contrib import admin from annuaire.models import * admin.site.register(Etablissement) admin.site.register(Personne) }}} * configurer le projet dans settings.py : {{{ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 'NAME': 'carto.db', # Or path to database file if using sqlite3. # ... } } INSTALLED_APPS = ( # ... 'annuaire', 'django.contrib.admin', # ... ) }}} * créer les tables dans la DB {{{ python manage.py syncdb }}} * saisir un jeu de données dans l'admin : http://127.0.0.1:8000 |
Ligne 37: | Ligne 132: |
== PARTIE 2 : HANDS-ON : PROJET ET APPLICATIONS == * Repartir du projet de l'atelier Backend si fait avant * ... sinon coder les modèles === Frontend : présenter les données === |
== PARTIE 2 : FRONTEND (INTERFACES PUBLIQUES) == === Frontend : présenter les données dans les interfaces publiques === ==== Frontend vs Backend ==== * public/privé : présentation données au public / gestion en privée * métaphore de boutique/entrepôt ou * métaphore de restaurant/cuisine ==== Flux d'info de requête à réponse ==== |
Ligne 45: | Ligne 145: |
https://docs.djangoproject.com/en/1.3/topics/http/urls/ * home |
https://docs.djangoproject.com/en/1.4/topics/http/urls/ {{{ urlpatterns = patterns('', url(r'^$', 'carto.views.home', name='home'), # ... ) }}} |
Ligne 49: | Ligne 154: |
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/ {{{ |
https://docs.djangoproject.com/en/1.4/topics/http/views/ ''voir tutoriel Part 3 (version shortcut)'' https://docs.djangoproject.com/en/1.4/intro/tutorial03/ Django 1.4 (>= 1.3) {{{ from django.shortcuts import render def home(request): c = { } return render(request, 'home.html', c) }}} Django 1.1.1 (<= 1.3) {{{ |
Ligne 63: | Ligne 180: |
https://docs.djangoproject.com/en/1.3/topics/templates/ | https://docs.djangoproject.com/en/1.4/topics/templates/ |
Ligne 65: | Ligne 182: |
Django 1.4 {{{carto/carto/templates/}}} Django 1.1.1 {{{carto/templates/}}} |
|
Ligne 68: | Ligne 190: |
# ... |
|
Ligne 69: | Ligne 194: |
# 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. |
|
Ligne 76: | Ligne 198: |
==== Utilisation de variables ==== |
|
Ligne 86: | Ligne 210: |
==== ORM : exploration interactive ==== |
|
Ligne 96: | Ligne 222: |
{{{ from personnes.models import * |
https://docs.djangoproject.com/en/1.4//topics/db/queries/ {{{ from annuaire.models import * |
Ligne 102: | Ligne 229: |
f = Personne.objects.get(id=1) f.id f = Personne.objects.get(id=314) e.id personnes = Personne.objects.filter(etablissement__nom__contains='Alexandrie') }}} * personnes/models.py |
p = Personne.objects.get(id=1) p.id p = Personne.objects.get(id=314) p.id personnes = Personne.objects.filter(universite__nom__contains='Montréal') }}} * annuaire/models.py |
Ligne 120: | Ligne 247: |
==== ORM : utilisation réelle ==== |
|
Ligne 130: | Ligne 259: |
== PARTIE 3 : PROJET RÉPERTOIRE BOOSTÉ == Télécharger les sources finales du projet boosté : sources finales [[attachment:sources.tar.gz]] |
==== Héritage de templates ==== * base.html {{{ {% block main %} {% endblock %} }}} * templates {{{ {% extends "base.html" %} {% block main %} }}} ==== URL avec paramètres ==== * pages de détail : capter l'id de l'objet * urls.py : import des urls de l'app annuaire * annuaire/urls.py {{{ urlpatterns = patterns('', # ... url(r'^', include('carto.annuaire.urls')), ) }}} * annuaire/views.py Django 1.4 {{{ from django.shortcuts import render from annuaire.models import Etablissement def etablissement_detail(request, id): etablissement = Etablissement.objects.get(id=id) c = { 'etablissement': etablissement, } return render(request, "annuaire/etablissement_detail.html", c) }}} Django 1.1.1 {{{ from django.shortcuts import render_to_response from django.template import Context, RequestContext from annuaire.models import Etablissement def etablissement_detail(request, id): etablissement = Etablissement.objects.get(id=id) c = { 'etablissement': etablissement, } return render_to_response("annuaire/etablissement_detail.html", Context(c), context_instance = RequestContext(request)) }}} * annuaire/templates/annuaire/etablissement_detail.html {{{ {{ etablissement }} }}} === Frontend pimpé === Télécharger les sources finales du projet pimpé : * sources finales Django 1.4 * [[https://wiki.auf.org/wikiteki/Ateliers/Django/Frontend/Support?action=AttachFile&do=get&target=carto_1_1_final.tar.gz|sources finales Django 1.1.1]] |
Ligne 135: | Ligne 326: |
* username : giotta | * username : admin |
Ligne 141: | Ligne 332: |
Boosté? 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.3/howto/static-files/ |
Pimpé? Quoi de neuf? ==== Fichiers statiques : CSS, images et js ==== https://docs.djangoproject.com/en/1.4/howto/static-files/ |
Ligne 185: | Ligne 363: |
=== Connexion du user === | ==== Connexion du user ==== |
Ligne 200: | Ligne 378: |
=== URL avec paramètres === * pages de détail : capter l'id de l'objet * urls.py : import des urls de l'app personnes * personnes/urls.py * personnes/views.py * templates/personnes/* === À faire : booster Admin : ModelAdmin === * personnes/admin.py * classes EtablissementAdmin, PersonneAdmin ''héritent de ModelAdmin'' * enregistrer Modele avec ModeleAdmin {{{ admin.site.register(Personne, PersonneAdmin) }}} * config ModeleAdmin {{{ list_display search_fields list_filter }}} * plus? https://docs.djangoproject.com/en/1.3/ref/contrib/admin/ * fields * fieldsets === Charger données initiales : fixtures === https://docs.djangoproject.com/en/1.3/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 FORMATION POUR LE PROJET RÉPERTOIRE == |
== EXERCICE == === Ajouter application Formation === ''Créer l'application formation pour le projet répertoire'' |
Ligne 258: | Ligne 392: |
=== Autre exercice : durée d'une Formation === | === Durée d'une Formation === |
Ligne 288: | Ligne 422: |
* Enjoy! | * Savourez! |
Django : Frontend : interfaces publiques d'un site
Sommaire
INTRODUCTION
- Objectifs
- présenter des données dans le frontend (interface publique) avec Django
- Documentation
- doc : bonne version de django
officielle : Django 1.4, Django 1.1
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) pas couvert ici (voir atelier Backend)
Part 3 : frontend couvert ici, plus directement même ;)
Part 4 : forms et vues génériques pas couvert ici
- doc : bonne version de django
- Environnement technique
Python >= 2.5
- Django 1.1.1 ou 1.4
- South 0.6 ou 0.7.4 (optionnel, recommandé)
- Vérification des versions :
>>> import django >>> django.get_version() '1.4' >>> import south >>> south.__version__ '0.7.4.'
- Django : version recommandée à l'AUF
- la version qui vient avec debian sur les serveurs de production
- sauf si vous êtes prêt à assurer une maintenance manuelle de Django
PARTIE 1 : RAPPELS ET AMORCE DU PROJET
Rappels
Ces rappels couvrent les parties 1 et 2 de l'atelier Backend
Développement web : schéma sur le développement web
- Django : les principaux fichiers dans l'architecture d'un projet
- Projet carto : définition du besoin et modélisation
Amorce du projet
Prendre ces sources avec jeu de données (recommandé):
superuser = admin/admin
- Projet carto : Django 1.4
Projet carto : Django 1.1.1
ou repartir de votre code du projet carto de l'atelier Backend si vous l'avez suivi avant
- ou partir à zéro en codant le projet :
django-admin.py startproject carto
- Django 1.1.1 :
django-admin startproject carto
cd carto python manage.py startapp annuaire
- Django 1.1.1 :
- coder les modèles de l'app annuaire : annuaire/models.py :
from django.db import models class Etablissement(models.Model): nom = models.CharField(max_length=255) sigle = models.CharField(max_length=50) def __unicode__(self): return self.nom class Personne(models.Model): nom = models.CharField(max_length=255) prenom = models.CharField(max_length=255, blank=True, null=True) date_naissance = models.DateField(blank=True, null=True) universite = models.ForeignKey('Etablissement', blank=True, null=True) def __unicode__(self): return "%s %s" % (self.nom.upper(), self.prenom)
- activer l'admin dans urls.py :
# ... from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # ... url(r'^admin/', include(admin.site.urls)), )
- associer les modèles de l'app annuaire à l'admin : créer annuaire/admin.py :
from django.contrib import admin from annuaire.models import * admin.site.register(Etablissement) admin.site.register(Personne)
- configurer le projet dans settings.py :
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 'NAME': 'carto.db', # Or path to database file if using sqlite3. # ... } } INSTALLED_APPS = ( # ... 'annuaire', 'django.contrib.admin', # ... )
- créer les tables dans la DB
python manage.py syncdb
saisir un jeu de données dans l'admin : http://127.0.0.1:8000
PARTIE 2 : FRONTEND (INTERFACES PUBLIQUES)
Frontend : présenter les données dans les interfaces publiques
Frontend vs Backend
- public/privé : présentation données au public / gestion en privée
- métaphore de boutique/entrepôt ou
- métaphore de restaurant/cuisine
Flux d'info de requête à réponse
- urls.py
https://docs.djangoproject.com/en/1.4/topics/http/urls/
urlpatterns = patterns('', url(r'^$', 'carto.views.home', name='home'), # ... )
- views.py
https://docs.djangoproject.com/en/1.4/topics/http/views/
voir tutoriel Part 3 (version shortcut)
https://docs.djangoproject.com/en/1.4/intro/tutorial03/
Django 1.4 (>= 1.3)
from django.shortcuts import render def home(request): c = { } return render(request, 'home.html', c)
Django 1.1.1 (<= 1.3)
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))
- templates
https://docs.djangoproject.com/en/1.4/topics/templates/
- créer répertoire templates
- Django 1.4
carto/carto/templates/
carto/templates/
- Django 1.4
- settings.py
import os # ... TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), "templates"), )
- templates/home.html
- créer répertoire templates
Utilisation de variables
- views.py
passer une variable au template
- templates/home.html
utiliser une variable :
{{ var }}
ORM : exploration interactive
- views.py
endroit où on code la logique en Python...
...plus simple si explore interactivement
python manage.py shell
- ORM (API) : object relationnal mapping
https://docs.djangoproject.com/en/1.4//topics/db/queries/
from annuaire.models import * etablissements = Etablissement.objects.all() for e in etablissements: print e e = etablissements[0] e.personne_set.all() p = Personne.objects.get(id=1) p.id p = Personne.objects.get(id=314) p.id personnes = Personne.objects.filter(universite__nom__contains='Montréal')
- annuaire/models.py
related_name = "personnes"
- relancer shell
e.personnes.all() e.personnes.count()
ORM : utilisation réelle
- views.py
passer les variables pertinentes pour accueil
- templates/home.html
boucle for dans template :
{% for e in etablissements %} {% endfor %}
Héritage de templates
- base.html
{% block main %} {% endblock %}
- templates
{% extends "base.html" %} {% block main %}
URL avec paramètres
- pages de détail : capter l'id de l'objet
- urls.py : import des urls de l'app annuaire
- annuaire/urls.py
urlpatterns = patterns('', # ... url(r'^', include('carto.annuaire.urls')), )
- annuaire/views.py
- Django 1.4
from django.shortcuts import render from annuaire.models import Etablissement def etablissement_detail(request, id): etablissement = Etablissement.objects.get(id=id) c = { 'etablissement': etablissement, } return render(request, "annuaire/etablissement_detail.html", c)
from django.shortcuts import render_to_response from django.template import Context, RequestContext from annuaire.models import Etablissement def etablissement_detail(request, id): etablissement = Etablissement.objects.get(id=id) c = { 'etablissement': etablissement, } return render_to_response("annuaire/etablissement_detail.html", Context(c), context_instance = RequestContext(request))
- Django 1.4
- annuaire/templates/annuaire/etablissement_detail.html
{{ etablissement }}
Frontend pimpé
Télécharger les sources finales du projet pimpé :
- sources finales Django 1.4
- superuser dans la DB de ces sources :
- username : admin
- password : admin
pour créer un autre superuser (le vôtre) :
python manage.py createsuperuser
Pimpé? Quoi de neuf?
Fichiers statiques : CSS, images et js
https://docs.djangoproject.com/en/1.4/howto/static-files/
- répertoire : static
- css
- images
- js
- settings.py
MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media') MEDIA_URL = '/media/' STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'sitestatic') STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(os.path.dirname(__file__), "static"), )
- urls.py
from django.contrib.staticfiles.urls import staticfiles_urlpatterns urlpatterns += staticfiles_urlpatterns()
Connexion du user
- templates
- connexion.html
- deconnexion.html
- urls.py
- connexion
- deconnexion
- settings.py
LOGIN_REDIRECT_URL = "/"
EXERCICE
Ajouter application Formation
Créer l'application formation pour le projet répertoire
Ajouter modèle Formation
- Formation
- nom
- date_debut
- date_fin
- etablissement
Durée d'une Formation
- Formation.duree()
"""Durée prévue en fonction des dates de début et de fin"""
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 :
- Channel IRC #django :
- Contribs, plugins
https://docs.djangoproject.com/en/dev/ref/contrib/
- south
- reversion
- Autre : pypi
- Savourez!