Modifications entre les versions 4 et 35 (s'étendant sur 31 versions)
Version 4 à la date du 2012-08-29 20:01:01
Taille: 6291
Éditeur: DavinBaragiotta
Commentaire:
Version 35 à la date du 2012-08-31 16:43:35
Taille: 10218
Éditeur: DavinBaragiotta
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


INTRODUCTION

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

  • 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

  1. Prendre ces sources avec jeu de données (recommandé):

    • superuser = admin/admin

    • Projet carto : Django 1.4
    • Projet carto : Django 1.1.1

  2. ou repartir de votre code du projet carto de l'atelier Backend si vous l'avez suivi avant

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


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

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)
        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
  • sources finales Django 1.1.1

  • 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

Ateliers/Django/Frontend/Support (dernière édition le 2012-08-31 16:43:35 par DavinBaragiotta)