- Finish and correct documentation
authorymh <ymh.work@gmail.com>
Sat, 05 Oct 2013 14:36:29 +0200
changeset 137 bb8bf2688d7e
parent 136 2afc9b5aab17
child 138 f01b65d6c724
- Finish and correct documentation - add some comments on the code
doc/_static/architecture.odg
doc/_static/architecture.png
doc/_static/p4l_connect.png
doc/_static/p4l_detail.png
doc/_static/p4l_edit.png
doc/_static/p4l_list.png
doc/administration.rst
doc/architecture.rst
doc/conf.py
doc/deploiement.rst
doc/description_interface.rst
doc/evolution.rst
doc/index.rst
src/p4l/api/serializers.py
src/p4l/mapping/parsers.py
src/p4l/utils.py
Binary file doc/_static/architecture.odg has changed
Binary file doc/_static/architecture.png has changed
Binary file doc/_static/p4l_connect.png has changed
Binary file doc/_static/p4l_detail.png has changed
Binary file doc/_static/p4l_edit.png has changed
Binary file doc/_static/p4l_list.png has changed
--- a/doc/administration.rst	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/administration.rst	Sat Oct 05 14:36:29 2013 +0200
@@ -1,5 +1,5 @@
 **************
-administration
+Administration
 **************
 
 Django et ses modules d'extensions propose de nombreuses commande d'administration. Le but est ici d'en lister les plus utiles pour l'administration de l'application.
@@ -29,6 +29,9 @@
 
 Voici une liste des commandes ser vant à gérer l'import et l'export des notices (``Record``). 
 
+
+.. _admin-import-record:
+
 ``import_record``
 -----------------
 
@@ -84,6 +87,10 @@
      Donc en cas d'erreur d'import il est possible que certaine notice ait été indexée mais ne se retrouve pas finalement en base.
      Il est à noté que dans ce cas, ces notices apparaîtrons dans la page de liste des notices.
 
+  #. Pour des imports massif, il est souvent plus interessant de desactiver l'indexation à la volée et de lancer si c'est possible une mise à jour de l'index (cf. `update_index`_) et sinon sa reconstruction. (cf. `rebuild_index`_) 
+
+
+.. _admin-dump-record:
 
 ``dump_record``
 ---------------
@@ -201,7 +208,7 @@
                             Verbosity level; 0=minimal output, 1=normal output,
                             2=verbose output, 3=very verbose output
       --settings=SETTINGS   The Python path to a settings module, e.g.
-                            "myproject.settings.main". If this isn't provided, the
+                            "myproject.settings.main". If this is not provided, the
                             DJANGO_SETTINGS_MODULE environment variable will be
                             used.
       --pythonpath=PYTHONPATH
--- a/doc/architecture.rst	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/architecture.rst	Sat Oct 05 14:36:29 2013 +0200
@@ -3,12 +3,33 @@
 Architecture 
 ************
 
-  - django
-    - rest framework
-    - rdflib
-    - haystack
-    - south
-  - postgresql
-  - sesame
-  - elasticsearch
-  - angularjs
\ No newline at end of file
+.. image:: _static/architecture.png
+
+
+L'application Back-Office Plan4Learning utilise les technologies suivantes: 
+
+*Django* - https://www.djangoproject.com/
+    C'est un framework web basé sur Python. de nombreux modules sont disponibles pour étendre ses fonctionnalités. 
+    En particulier, nous utilisons les modules suivant: 
+
+    * *South* - http://south.aeracode.org/. Ce module permet de gérer les migration de bases de données (schéma + données).
+      On peut alors facilement appliquer les changements du modèle de donnée sur un système en production.   
+    * *Django REST Framework* - http://django-rest-framework.org/ : Permet de facilement de facilement mettre en oeuvre une API de type REST.
+    * *haystack* - http://haystacksearch.org/ : Facilite l'utilisation dans Django des moteurs d'indexation full-text comme Lucene ou elasticsearch
+
+*Postgresql* - http://www.postgresql.org/
+    Base de donnée relationnelle. Nous l'utilisons en fait par l'intermédiaire de la couche ORM de Django
+
+*Sesame* - http://www.openrdf.org/
+    C'est en fait un framework de gestion RDF. Nous l'utilison ici comme triple store RDF et endpoint SPARQL
+
+*Elasticsearch* - http://www.elasticsearch.org/
+    Moteur d'indexation full-text basé sur Lucene. Nous l'utilisons par l'intermédiaire du module Django Haystack.   
+
+*Angularjs* - http://angularjs.org/
+    Framework javascript. Nous l'utilisons en particulier dans la page d'édition des notices afin de gérer les interactions complexes entre la notice et ses sous-objets.
+    
+*Bootstrap* - http://getbootstrap.com/
+    Framework CSS. Il a été utilisee sur toutes les pages de l'application.
+    
+    
\ No newline at end of file
--- a/doc/conf.py	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/conf.py	Sat Oct 05 14:36:29 2013 +0200
@@ -59,7 +59,7 @@
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
-#language = None
+language = 'fr'
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
@@ -155,13 +155,13 @@
 #html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+html_use_index = False
 
 # If true, the index is split into individual pages for each letter.
 #html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+html_show_sourcelink = False
 
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
 #html_show_sphinx = True
--- a/doc/deploiement.rst	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/deploiement.rst	Sat Oct 05 14:36:29 2013 +0200
@@ -81,8 +81,14 @@
 Sesame
 ------
 
-Attention, l'application "BO Plan4Learning" nécessite la présence d'un serveur Sesame comprenant l'ensemble des référentiels et thésaurus de l'application.
-L'installation d'un tel erveur est hors du scope de cette documentation.
+L'application "BO Plan4Learning" nécessite la présence d'un serveur Sesame comprenant l'ensemble des référentiels et thésaurus de l'application.
+
+L'installation d'un tel serveur est hors du scope de cette documentation.
+
+Une partie de l'application accède au serveur Sesame directement en javascript depuis le navigateur de l'utilisateur.
+Si le serveur Sesame est sur un autre domaine que l'application Back-Office (même si seulement le numéro de port change), 
+il est nécessaire qu'il supporte les en-têtes CORS (c.f. http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) en autorisant le domaine de l'application Back-Office. 
+
 
 
 Etapes de déploiement
@@ -128,8 +134,11 @@
 Configuration
 -------------
 
-La configuration du système se fait dans le fichier ``src/config.py``. Ce fichier doit être créé à partir du fichier ``src/config.py.tmpl``.
-La plupart des configurations sont soit documentées directement dans le fichier, soit documentés à l'adresse suivante : https://docs.djangoproject.com/en/1.5/ref/settings/
+La configuration du système se fait dans le fichier ``src/p4l/config.py``. Ce fichier doit être créé à partir du fichier ``src/config.py.tmpl``.
+La plupart des configurations sont soit documentées directement dans le fichier, soit documentés à l'adresse suivante : https://docs.djangoproject.com/en/1.5/ref/settings/)
+
+Il existe un autre fichier de configuration : ``src/p4l/settings.py``. C'est en fait le fichier "normal" de configuration de Django (cf. https://docs.djangoproject.com/en/1.5/topics/settings/) .
+Techniquement, les propriétés de ``config.py`` viennent redéfinir une partie de celles de ``settings.py``. Néanmoins lors d'un déploiement, seule le fichier ``config.py`` doit être modifié.
 
 
 Création de la base
--- a/doc/description_interface.rst	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/description_interface.rst	Sat Oct 05 14:36:29 2013 +0200
@@ -2,16 +2,82 @@
 Description de l'interface
 **************************
 
-4 écrans
+L'application est constituée de 4 écrans.
+Ces écrans sont des pages html5.
+Ces pages utilisent le framework css Bootstrap (http://getbootstrap.com/).
 
-connection
+
+Connection
 ==========
 
-liste des notices
+.. image:: _static/p4l_connect.png
+    :width: 600pt
+
+Toutes les pages de l'application sont protégées par un système de login/mot de passe.
+Ce dialogue de connection s'affiche lorsque l'utilisateur essaye d'accéder à une des pages de l'application et qu'il n'est pas connecté.
+
+
+
+Liste des notices
 =================
 
-visionnage d'une notice
+.. image:: _static/p4l_list.png
+    :width: 600pt
+
+Cet écram donne la liste des notices et permet la recherche.
+La recherche se fait sur l'identifiant d'une notice, le(s) titre(s) d'une notice et les autheurs (personnes ou institutions).
+
+Les notices sont toujours affichés dans l'ordre de leur identifiant (tri lexicographique ascendant).
+
+En haut de la liste un bouton permet l'ouverture du dialogue de création d'une nouvelle notice.
+Pour chaque notice de la liste 2 boutons sont proposés : vue de du détail de la liste ou bien édition. 
+
+
+En haut de la page se trouve un champ de recherche permettant le filtrage des notices.
+C'est une recherche de type full-text qui porte sur les champs suivants des notices :
+  
+    * identifiant
+    * titres (dans toutes les langues)
+    * années de publication
+    * autheurs (personnes et entités)
+
+Le champ de recherche permet l'utilisation d'un mini language de requête décrit à l'adresse suivante : http://pythonhosted.org/Whoosh/querylang.html
+Les points à noter à ce ce sujet sont :
+  
+    * L'opérateur par défaut est le ``OR``.
+    * la valeur du spécifieur ``field`` doit être dans la liste suivante : ``identifier``, ``titles``, ``years``, ``authors``.
+
+
+.. _interface-detail:
+
+Visionnage d'une notice
 =======================
 
+.. image:: _static/p4l_detail.png
+    :width: 600pt
+
+Cet écran donne accès à l'affichage du deetail d'une notice. Deux boutons permettent soit de passer à l'écran d'édition de la notice, soit de pouvoir l'éfacer.
+Un dialogue de confirmation de l'effacement sera affiché préalablement à l'utilisateur.
+Par contre, tout effacement d'une notice est définitif.
+
+
+.. _interface-edit:
+
 Édition d'une notice
 ====================
+
+.. image:: _static/p4l_edit.png
+    :width: 600pt
+
+Cet écran permet l'édition d'une notice (nouvelle ou bien existante).
+Un bouton d'annulation permet d'interrompre l'édition d'une fiche à tout moment.
+Les modifications d'une fiche (ou bien sa création) ne seront sauvegardées seulement après avoir appuyer sur le boouton de sauvegarde.
+
+Toute navigation hors de cet écran que ce soit en cliquant sur l'un des lien ou un des boutons de l'interface ou que ce soit en utilisant les fonctionalité du navigateur annulera sans prévenir l'édition en cours.
+Tout les changements non sauvegardés seront perdus.
+
+Tous les champs sont éditables, a part les champs "identifiant" et "URI" qui sont en lecture seule.
+
+Deux boutons sont disponibles pour accéder au deetail de la notice ou bien à son effacement. Dans ce dernier cas un dialogue de confirmation sera affiché anant l'effacement définitif de la notice.
+
+  
\ No newline at end of file
--- a/doc/evolution.rst	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/evolution.rst	Sat Oct 05 14:36:29 2013 +0200
@@ -1,3 +1,6 @@
+:tocdepth: 4
+:tocmaxdepth: 3
+
 *********
 Évolution
 *********
@@ -5,22 +8,280 @@
 Internationalisation
 ====================
 
-gettext
-ref django
-fichiers src/p4l/locale/*/LC_MESSAGES/django.po
+Le système d'internationalisation (i18n) utilise le mécanisme fourni par Django.
+
+Il est documenté aux adresses suivantes :
+  * https://docs.djangoproject.com/en/1.5/topics/i18n/ et
+  * https://docs.djangoproject.com/en/1.5/topics/i18n/translation/
+
+Ce mécanisme est basé sur l'utilitaire `gettext <http://www.gnu.org/software/gettext/manual/gettext.html#Concepts>`_.
+
+En particulier, dans l'arborescence des sources de l'application, les fichiers ``src/p4l/locale/*/LC_MESSAGES/django.[po,mo]`` sont les fichiers de resources de langues.
+Les fichier éditable sont les fichiesr ``.po``.
 
-makemessages -a
-compilemessages
+Deux commandes d'administration sont fournies par Django pour gérer les fichiers de resources de traduction:
+
+
+  * ``makemessages`` : https://docs.djangoproject.com/en/1.5/ref/django-admin/#django-admin-makemessages.
+    C'est la commande permettant la création et la mis ā jour des fichiers ``.po``.
+    Cette commande extrait des fichier sources de l'application les chaîne de caractères à traduire et les places dans les fichier ``.po``.
+    Typiquement, on ne lancera cette commande que si de nouvelle chaînes à trduire sont ajoutées dans l'application.
+     
+  * ``compilemessages`` : Compile les fichiers ``.po`` contitués par la commande précédente afin que les traduction soit prise en compte.
+    cette commande produit les fichier ``.mo``. 
 
 
 modification des champs
 =======================
 
-liste des points à modifier
+La modification de la liste des champs traitée par le back-office nécessite des changements a plusieurs niveaux.
+Voici une liste des points à modifier.
+
+  * Dans la :ref:`configuration <evol-config>` (``settings.py``) : les propriétés ``SPARQL_REF_QUERIES`` et ``RDF_SCHEMES``
+  * :ref:`Évolution du schéma <evol-schema>` de la base de données
+  * :ref:`Modification du parser <evol-parser>` pour l'import.
+  * :ref:`Modification du sérialiseur <evol-serializer>` pour l'export 
+    + modification de la constante ``p4l.mapping.constants.GRAPH_NAMESPACES``
+  * :ref:`Modification du serialiseur rest <evol-rest-serializer>`.
+  * 
+  * modification de l'écran d'affichage du :ref:`détail <evol-detail>` d'une notice.
+  * modification de l'écran d':ref:`édition <evol-edition>` d'une notice.
+  
+La description de ces modifications se base sur la condition que le type de champ ajouté est le même qu'un champ déjà existant.
+La création d'un nouveau type de champ est hors du scope de cette documentation, 
+mais l'examen attentif des points suivants pourront être un point de dépard pour le développement. 
+
+
+.. _evol-config:
+
+Modification de la configuration
+--------------------------------
+
+Cette modification concerne seulement les champs dont la(es) valeur(s) est(sont) contrôlé(s) par un référentiel.
+Les deux propriétés concernées sont ``SPARQL_REF_QUERIES`` et ``RDF_SCHEMES``. ce sont deux dictionnaires ayant les mêmes valeurs de clef.
+Chaque clef correspond à un référentiel.
+
+.. _evol-config-SPARQL-REF-QUERIES:
+
+``SPARQL_REF_QUERIES``
+^^^^^^^^^^^^^^^^^^^^^^
+
+les valeurs de ce dictionnaire sont elle même un dictionnaire qui contient les requêtes SPARQL d'exploration des reeférentiels.
+les clés suivantes sont à renseigner:
+
+    * ``url`` : url du endpoint pour ce référentiel. On n'y mettra ``SPARQL_QUERY_ENDPOINT`` la plupart du temps.
+    * ``filter`` : requête filtrant les entrées du référentiel selon une partie de terme.
+      Cette requète est utiliser pour faire de l'autocomplétion.
+    * ``root`` : Requête qui donne les racines des référentiels en arbre et l'ensemble des termes pour les autres
+    * ``childs`` : Requ6ete donnant les enfants d'un noeud particulier pour les référentiel "arbre".
+      Cette clé n'a pas besoin d'être renseigné pour les autres.
+    * ``child-count`` : Nombre denfant pour 1 noeud d'un référentiel arbre. N'a pas besoin d'être renseignee pour les autres.
+ 
+ 
+``RDF_SCHEMES``
+^^^^^^^^^^^^^^^
+
+Ce dictionnaire donne les uri des ``scheme`` des référentiels. 
+
+
+.. _evol-schema:
+
+Modification du schema de la base de donnée
+-------------------------------------------
+
+Modification du modèle Django
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+La première étape consiste à modifier le modèle Django.
+La documentation Django sur les modèle se trouve à l'url suivante https://docs.djangoproject.com/en/1.5/topics/db/models/
+
+le modèle du projet se trouve dans ``src/p4l/models`` et en particulier la définition d'une notice (objet ``Record``) dans ``src/p4l/models/data.py``.
+ce fichier contient toute les définitions des champs actuellement utilisés et pourra servir de base d'exemple pour les évolutions envisagées.
+ 
+Attention, contrairement à la documentation Django, il ne faut pas appliquer pas la commande ``syncdb`` pour mettre à jour le schema de la base de donnée.
+
+
+Utilisation de South
+^^^^^^^^^^^^^^^^^^^^
+
+Pour assurer la gestion des migration de modèle de donnée sur des base en production nous utilison le module Django South : http://south.aeracode.org/.
+
+L'utilisation de ce module passe par la création de migrations.
+
+En particulier nous suivons l'exemple donné à l'url suivante:
+http://south.readthedocs.org/en/latest/tutorial/part1.html#changing-the-model
+
+Les commandes ajoutées par South sont documentées à l'adresse suivante :
+http://south.readthedocs.org/en/latest/commands.html
+
+
+.. _evol-parser:
+
+Modification du parser pour l'import
+------------------------------------
+
+L'import des notice au format rdf se fait avec la commande ``import_record`` (cf :ref:`admin-import-record`).
+Cette commande sépare le fichier rdf en sous graphes rdf, un par objet ``Record``.
+Ces graphes sont alors pris en présent à un parser qui se charge de leur transformation en objets ``Record``.
+
+Le parser est définit dans le fichier ``src/p4l/mapping/parsers.py``, plus particulièrement dans la classe ``RecordParser``.
+La définition des champs et des sous-objets se fait dans la méthode ``build_record``.
+
+Le parsing des données du graphe se fait en fait à l'aide de deux méthodes principales défines sur la classe ``RecordParser``:
+
+  * ``extract_single_value_form_graph`` : permet d'extraire une valeur simple du graphe. elle est utilisée pour les champs simples monovalués.
+  * ``extract_multiple_values_from_graph`` : Gère l'ajout d'objet à un gestionnaire d'objets liés ("related object manager" : https://docs.djangoproject.com/en/1.5/ref/models/relations/).
+    Les données nécessaire pour la création des objets sont extraites du graphe. 
+
+
+Points à noter:
+
+  #. les champs simples doivent être positionnés avant la sauvegarde de la notice (appel à la méthode save du modèle ``Record``).
+     Par contre les champs complexes (sous objets, champs multivalués,...) doivent être traités après l'appel à ``.save()``
+  #. Lorsqu'une notice est mise à jour, l'objet ``Record`` et ces dépendances sont effacés et recréés
+  #. Sauf pour les champs gérés par un référentiel, ll y a une relation d'aggregation entre l'objet ``Record`` et ses sous objets.
+     Dans le cas des champs complexes avec référentiel, c'est une relation multiple (many to many).
+     Dans ce cas lors de l'effacement d'un object ``Record``, seul les entrées dans les tables de liason sont effacées. Les entrée dans les tables de référentiel se sont pas affectées.
+  #. Sur les champs avec référentiel, il n'y a pas de validation. Les entrées dans les tables de référentiels sont crées à la demande, sans validation par rapport au repository Sésame.      
+  #. L'ensemble de la création (ou de l'effacement) d'un objet ``Record`` et de ces dépendances est fait dans une transaction.
+ 
+
+.. _evol-serializer:
+
+Modification du serialiseur pour l'export
+-----------------------------------------
+
+l'export des notices au format rdf se fait avec la commande ``dump_record`` (cf :ref:`admin-dump-record`).
+Chaque objet ``Record`` concerné par l'export est transformé en graphe rdf par un serialiseur. Le graphe rdf est ensuite sérialisé en xml.
+
+Le serializer est défini dans le fichier ``src/p4l/mapping/__init__.py`` et fait appel à des resources se trouvant dans ``src/p4l/mapping/serializers.py``. 
+
+Les interfaces définies dans ce modules sont inspirées de celle proposée par le module ``Rest framework`` que nous utilisons par ailleurs (cf. :ref:`evol-rest-serializer`).
+En particulier on pourra lire la documentation des ``serializer``: http://django-rest-framework.org/api-guide/serializers.html .
+
 
-  - settings : SPARQL_REF_QUERIES, RDF_SCHEMES
-  - base de données : utilisation de south
-  - description import
-  - modification export
-  - modification écran d'affichage
-  
+.. _evol-rest-serializer:
+
+Modification du serialiseur REST
+--------------------------------
+
+Une partie de l'application (l'édition des notices) dépend d'interface REST proposant du JSON.
+Pour cela nous utilisons le module "Django REST Framework".
+La documentation de ce module se trouve à l'adresse suivante : http://django-rest-framework.org/ .
+
+La classe à modifier est ``RecordSerializer`` qui se trouve dans le fichier ``src/p4l/api/serializers.py``.
+La documentation sur les ``serializer`` du Rest Framework est à l'adresses suivante : http://django-rest-framework.org/tutorial/1-serialization.html.
+La documentation de l'api des serializer se trouve aux url suivantes : http://django-rest-framework.org/api-guide/serializers.html, http://django-rest-framework.org/api-guide/fields.html, http://django-rest-framework.org/api-guide/relations.html.
+
+Nous utilisons les mécanismes standarts de sérialisation du ``REST Framework``. Nous avons juste adaptee les points suivants:
+
+  * Pour les champs contrôlés par un référentiel, le mécanisme standart du ``REST Framework`` est d'accepter les valeurs que si elle sont déjà présente dans la base.
+    Nous avons changé ce comportement pour accepter toute les valeurs et de créer les nouvelles à la demande. Ceci a été fait pour simplifier la gestion des référentiels et la centraliser en amont du back office.
+    Ceci est implémenté dans la classe ``p4l.api.serializers.ThesaurusSerializer``.
+  * Pour les champs multiples et les sous-objets, l'ID de l'objet en base n'est pas sérialisée. Ceci se trouve dans la classe ``p4l.api.serializers.P4lModelSerializer``.
+  * Lors d'un update, les sous-objets sont effacés puis recréés. cela a pour conséquence qu'un update partiel n'est pas possible. A chaque requête de mise à jour, l'ensemble de l'objet ``Record`` et de tous ses sous-objets doit être envoyé à l'API REST d'update. 
+  * Une modification du seerializer REST n'est nécessaire que si le nouveau champ est contrôlé par un référentiel (bien sur si ce nouveau champs est d'un type déjà supporté par l'application).
+
+
+.. _evol-ref-labels:
+
+Modification de la récupération des labels des champs contrôlés par référentiel
+-------------------------------------------------------------------------------
+
+L'application ne gère pas les labels des valeurs des champs contrôlés par référentiel.
+Pour l'affichage dews notices il est donc nécessaire de préalablement requêter tous ces labels.
+
+Ce requêtage se fait dans la méthode ``p4l.views.fill_label_for_model`` (dans le fichier ``src/p4l/views.py``).
+Cette méthode retourne un dictionnaire où les clefs sont les uri des termes, et les valeurs les labels correspondants dans la langue demandées.
+
+Bien sur aucune modification est nécessaire si le champ ajouté ou modifié n'introduit pas un nouveau référentiel.
+
+
+.. _evol-detail:
+
+Modification de l'écran de détail
+---------------------------------
+
+L'écran de détail d'une notice (c.f. :ref:`interface-detail`) utilise le couple classique vue/template Django.
+
+La documentation Django sur les vues est à l'url suivante : https://docs.djangoproject.com/en/1.5/topics/class-based-views/.
+La documentation Django sur les template est ici : https://docs.djangoproject.com/en/1.5/topics/templates/.
+
+La vue d'affichage du détail d'une notice est générée par la classe suivante : ``p4l.views.RecordDetailView`` (dans le fichier ``src/p4l/views.py``).
+Le template d'affichage du détail est le suivant : ``src/templates/p4l/record_view.html``.
+
+Normalement seul le template a besoin d'être modifié. Les champs déjà présents pourront être pris comme exemple pour introduire le nouveau champ.
+
+
+.. _evol-edition:
+
+Modification de l'écran d'édition
+---------------------------------
+
+Comme pour l'écran de détail, l'écran d'édition d'une notice (c.f. :ref:`interface-edit`) utilise un couple vue/template Django. (c.f. :ref:`evol-detail` pour les url de documentation Django)
+Par contre les fonctionnalités de cette page sont nettement plus complexes dans leur mise en oeuvre.
+
+La vue d'édition d'une notice est générée par la classe suivante : ``p4l.views.RecordEditView`` (dans le fichier ``src/p4l/views.py``).
+Le template d'affichage du détail est le suivant : ``src/templates/p4l/record_update_form.html``.
+Par ailleurs la vue d'édition est en fait une véritable application web ("webapp") basée sur la librairie Angularjs (http://angularjs.org/).
+Elle est implémentée dans le fichier ``src/p4l/static/p4l/js/p4l.js``.
+La page fait aussi appel à des resources (des templates) dans le reepertoire ``src/p4l/static/p4l/template``.
+
+Normalement, seul les fichiers template Django ``src/templates/p4l/record_update_form.html`` ou bien angular ``src/p4l/static/p4l/templates`` auront besoin d'être modifiés pour ajouter ou modifier un champs d'un type déjà existant.
+
+Lors du chargement de la page d'édition, les données de la notice sont chargée à partir de la couche d'API REST sous forme d'objets sérialisés en JSON.
+Ces données viennent remplir le "modèle" de l'appli web.
+Ce modèle est ensuite exploité dans une série de directives Angularjs (c.f. http://docs.angularjs.org/guide/directive) qui permettent l'éditions des différents champs et sous-objets de la notice.
+Lors de la sauvegarde, ce modèle est sérialisé en JSON et soumis par requête http à la couche d'API REST de l'application.
+ 
+Le formulaire d'édition utilise 4 types d'éléments pour gérer les différents champs et sous-objets de l'objet notice.
+
+  * Pour les champs simples: des contôles html (``input``, ``textarea``...) liés au modèle dans un formulaire Angularjs (http://docs.angularjs.org/guide/forms)
+  * Pour les champs simples liés à un référentiel : la directive :ref:`simple-sem-uri <evol-edition-simple-sem-uri>`.
+  * Pour les champs complexes liés à un référentiel : la directive :ref:`add-sem-uri <evol-edition-add-sem-uri>`.
+  * Pour les champs complexes autres (sous-objets) : la directive :ref:`object-list <evol-edition-object-list>`.
+ 
+Les contrôles html et l'usage qu'Angularjs en fait sont documentés dans la référence d'API : http://docs.angularjs.org/api/.
+Le reste des directives est documenté ci-après et on pourra se basé sur les champs existant pour aveoir des exemple d'utilisation.
+
+.. _evol-edition-simple-sem-uri:
+
+Directive ``simple-sem-uri``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  * ``val`` : le champ du modèle lié à cette directive.
+  * ``listname`` : Une des clefs du paramètre de configuration ``SPARQL_REF_QUERIES`` (c.f. :ref:`evol-config-SPARQL-REF-QUERIES`)
+  * ``placeholder`` : texte d'aide du champs de saisie pour le référentiel.
+
+
+.. _evol-edition-add-sem-uri:
+
+Directive ``add-sem-uri``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  * ``list`` : le champ du modèle lié à cette directive, ce doit être une liste (champ multivalué).
+  * ``listname`` : Une des clefs du paramètre de configuration ``SPARQL_REF_QUERIES`` (c.f. :ref:`evol-config-SPARQL-REF-QUERIES`)
+  * ``placeholder`` : texte d'aide du champs de saisie pour le référentiel.
+
+
+.. _evol-edition-object-list:
+
+Directive ``object-list``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  * ``form-template`` : nom d'un template pour l'édition des sous-objets.
+  * ``disp-template`` : nom d'un template pour gérer l'affichage des sous-objets. Ce paramêtre est optionnel en mode table.
+    Si ce paramêtre est vide, un template est automatiquement généré.
+  * ``object-list`` : le champ du modèle lié à cette directive, ce doit être une liste (champ multivalué).
+  * ``object-fields`` : Liste des champs du sous-objet à afficher en mode table.
+  * ``table`` : Affiche les sous objets en table ou pas.
+  * ``size-fields`` : Largeur des colonnes pour le mode table. L'ordre des colonnes est le même que pour ``object-fields``.
+    L'unité est une colonne définie par le système de grille Bootstrap : http://getbootstrap.com/css/#grid.
+  * ``label-fields`` : Label des colonnes pour le mode table. Ces labels sont traduits. L'ordre des colonnes est le même que pour ``object-fields``.
+
+Les templates définis par les paramêtres ``form-template`` et ``disp-template`` se trouvent dans le répertoire ``src/p4l/static/p4l/templates``.
+Ce sont des templates Angularjs (c.f. http://docs.angularjs.org/guide/dev_guide.templates).
+Pour les template ``form-template``, l'objet édité est dans la variable ``editedObj``.
+Pour les template ``disp-template``, l'objet édité est dans la variable ``obj``. 
+Les templates existant donneront des exemples d'utilisation et pourront servir de base pour l'ajout d'un nouveau champ.
+
--- a/doc/index.rst	Wed Oct 02 05:30:19 2013 +0200
+++ b/doc/index.rst	Sat Oct 05 14:36:29 2013 +0200
@@ -9,7 +9,7 @@
 Contenu:
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 3
    :numbered:
 
    architecture
--- a/src/p4l/api/serializers.py	Wed Oct 02 05:30:19 2013 +0200
+++ b/src/p4l/api/serializers.py	Sat Oct 05 14:36:29 2013 +0200
@@ -140,7 +140,6 @@
 
 
 
-#class RecordSerializer(serializers.ModelSerializer):
 class RecordSerializer(P4lModelSerializer):
     '''
     Serializer for record
--- a/src/p4l/mapping/parsers.py	Wed Oct 02 05:30:19 2013 +0200
+++ b/src/p4l/mapping/parsers.py	Sat Oct 05 14:36:29 2013 +0200
@@ -68,11 +68,35 @@
         if self.query_cache is None:
             self.query_cache = QueryCache()        
     
+        
     def extract_single_value_form_graph(self, graph, q, bindings={}, index=0, convert=lambda v:unicode(v) if v is not None else None, default=None):
+        '''
+        Extract a single value form an rdf graph.
+        
+        :param graph: the rdflib.Graph object to parse
+        :param q: the SPARQL query used to extact the data from the graph
+        :param bindings: Optional binding values for the query
+        :param index: zero based index of the result to extract
+        :param convert: Either a single method of a map of method to apply to the data to extract 
+        :param default: The default value to return if no result is returned by the query
+        
+        @return: None or a single value        
+        '''
         return next(self.extract_multiple_values_from_graph(graph, q, bindings, index, convert), default)
 
+
     def extract_multiple_values_from_graph(self, graph, q, bindings={}, index=0, convert=lambda v:unicode(v) if v is not None else None):
-
+        '''
+        Extract multiple values from a rdf graph.
+        
+        :param graph: the rdflib.Graph object to parse
+        :param q: the SPARQL query used to extact the data from the graph
+        :param bindings: Optional binding values for the query
+        :param index:  zero based index of the result to extract
+        :param convert: The default value to return if no result is returned by the query
+        
+        @return: an iterator on the extracted values
+        '''
         index_list = index
         if isinstance(index, int):
             index_list = range(index+1)
@@ -111,6 +135,18 @@
 
 
     def add_to_related_collection(self, coll, graph, fields, q, bindings={},  convert=lambda v: unicode(v) if v is not None else None, through_fields=None):
+        '''
+        This method add new object to a related object collection by extracting data from an rdflib.Graph.
+        
+        
+        :param coll: The collection to add the new objects into. This must be a related collection (cf. django)
+        :param graph: The graph from wich data is extracted
+        :param fields: The list of fields to extract
+        :param q: The SPAQL query. The order and number of the binding parameters of the query must be equals to the one descibed in the ``fields`` parameter.
+        :param bindings: Binding for the SPARQL qery
+        :param convert: map of methods or simple method  to convert data extracted form the graph.
+        :param through_fields: the list (in order) of the througt table used to make a relation between the main object and an "external" object.
+        '''
         
         for val in self.extract_multiple_values_from_graph(graph, q, bindings=bindings, index=fields, convert=convert):
 
--- a/src/p4l/utils.py	Wed Oct 02 05:30:19 2013 +0200
+++ b/src/p4l/utils.py	Sat Oct 05 14:36:29 2013 +0200
@@ -84,6 +84,14 @@
 
 
 def get_labels_for_uris(uri_list, scheme_uri, lang, acronyms=False):
+    '''
+    This methods gathers labels for concept in thesaurus.
+    
+    :param uri_list: The list of uris of thesaurus entries.    
+    :param scheme_uri: The scheme (uri) of the thesaurus 
+    :param lang: The language for the label
+    :param acronyms: do the labels must include the acronym (altLabel) 
+    '''
     query_without_acronym = """
 PREFIX skos:<http://www.w3.org/2004/02/skos/core#>
 PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>