From 1325f1851d247a5494026596c6c13437b0e1a676 Mon Sep 17 00:00:00 2001 From: Fred Pauchet Date: Wed, 13 Apr 2016 16:08:38 +0200 Subject: [PATCH] change forms --- source/forms.rst | 19 +++++++++++++++++++ source/forms/05-forms.rst | 14 +++++++------- source/models.rst | 1 + source/models/key-points.rst | 2 -- source/models/metamodel.rst | 9 +++++++++ source/models/user-management.rst | 1 - 6 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 source/models/metamodel.rst diff --git a/source/forms.rst b/source/forms.rst index c6b5d39..89afdbd 100644 --- a/source/forms.rst +++ b/source/forms.rst @@ -1,3 +1,22 @@ =========== Formulaires =========== + +Quand on parle de ``forms``, on ne parle pas uniquement de formulaires Web. On pourrait considérer qu'il s'agit de leur objectif principal, mais on peut également voir un peu plus loin: on peut en fait voir les ``forms`` comme le point d'entrée pour chaque donnée arrivant dans notre application: il s'agit en quelque sorte d'un ensemble de règles complémentaires à celles déjà présentes au niveau du modèle. + +L'exemple le plus simple est un fichier ``.csv``: la lecture de ce fichier pourrait se faire de manière très simple, en récupérant les valeurs de chaque colonne et en l'introduisant dans une instance du modèle. Mauvaise idée. Les données fournies par un utilisateur **doivent** **toujours** être validées avant introduction dans la base de données. Notre base de données étant accessible ici par l'ORM, la solution consiste à introduire une couche supplémentaire de validation. + +Le flux à suivre est le suivant: + + 1. Création d'une instance grâce à un dictionnaire + 2. Validation des informations reçues + 3. Traitement, si la validation a réussi. + +On définit un form comme une classe. Comme pour l'ORM, des attributs Meta peuvent être ajoutés, afin de récupérer automatiquement des + +########## +Conclusion +########## + + 1. Toute donnée entrée par l'utilisateur **doit** passer par une instance de ``form``. + 2. diff --git a/source/forms/05-forms.rst b/source/forms/05-forms.rst index a674bd3..f1c6e59 100644 --- a/source/forms/05-forms.rst +++ b/source/forms/05-forms.rst @@ -21,12 +21,12 @@ Un **form** peut dépendre d'une autre classe Django. Pour cela, il suffit de fi fields = ('name', 'description') -De cette manière, notre form dépendra automatiquement des champs déjà déclarés dans la classe `Wishlist`. Cela suit le principe de [DRY](don't repeat yourself), et évite qu'une modification ne pourrisse le code: en testant les deux champs présent dans l'attribut `fields`, nous pourrons nous assurer de faire évoluer le formulaire en fonction du modèle sur lequel il se base. +De cette manière, notre form dépendra automatiquement des champs déjà déclarés dans la classe ``Wishlist``. Cela suit le principe de `DRY `_, et évite qu'une modification ne pourrisse le code: en testant les deux champs présent dans l'attribut ``fields``, nous pourrons nous assurer de faire évoluer le formulaire en fonction du modèle sur lequel il se base. Contrôle du rendu ================= -Le formulaire permet également de contrôler le rendu qui sera appliqué lors de la génération de la page. Si les champs dépendent du modèle sur lequel se base le formulaire, ces widgets doivent être initialisés dans l'attribut `Meta`. Sinon, ils peuvent l'être directement au niveau du champ. +Le formulaire permet également de contrôler le rendu qui sera appliqué lors de la génération de la page. Si les champs dépendent du modèle sur lequel se base le formulaire, ces widgets doivent être initialisés dans l'attribut ``Meta``. Sinon, ils peuvent l'être directement au niveau du champ. .. code-block:: python @@ -41,13 +41,13 @@ Le formulaire permet également de contrôler le rendu qui sera appliqué lors d widgets = { 'date' : forms.TextInput( attrs={ - 'class' : 'form-control', - 'data-provide' : 'datepicker', - 'data-date-format' : 'dd/mm/yyyy', + 'class' : 'form-control', + 'data-provide' : 'datepicker', + 'data-date-format' : 'dd/mm/yyyy', 'placeholder' : date.today().strftime("%d/%m/%Y") - }), + }), 'information' : forms.Textarea( attrs={ - 'class' : 'form-control', + 'class' : 'form-control', 'placeholder' : 'Context (why, where, ...)' }) diff --git a/source/models.rst b/source/models.rst index 46a9046..9fabae0 100644 --- a/source/models.rst +++ b/source/models.rst @@ -47,3 +47,4 @@ Les classes sont créées, mais vides. Entrons dans les détails. .. include:: models/console.rst +.. include:: models/metamodel.rst diff --git a/source/models/key-points.rst b/source/models/key-points.rst index 2a25444..8973bea 100644 --- a/source/models/key-points.rst +++ b/source/models/key-points.rst @@ -92,5 +92,3 @@ A partir de maintenant, on peut accéder à nos propriétés de la manière suiv [] Remarque: si, dans une classe A, plusieurs relations sont liées à une classe B, Django ne saura pas à quoi correspondra la relation inverse. Pour palier à ce problème et pour gagner en cohérence, on fixe alors une valeur à l'attribut ``related_name``. - - diff --git a/source/models/metamodel.rst b/source/models/metamodel.rst new file mode 100644 index 0000000..092b99b --- /dev/null +++ b/source/models/metamodel.rst @@ -0,0 +1,9 @@ +********** +Métamodèle +********** + +Sous ce titre franchement pompeux, on va un peu parler de la modélisation du modèle. Quand on prend une classe (par exemple, ``Wishlist`` que l'on a défini ci-dessus), on voit qu'elle hérite par défaut de ``models.Model``. On peut regarder les propriétés définies dans cette classe en analysant le fichier ``lib\site-packages\django\models\base.py``. On y voit notamment que ``models.Model`` hérite de ``ModelBase`` au travers de `six `_ pour la rétrocompatibilité vers Python 2.7. + +Cet héritage apporte notamment les fonctions ``save()``, ``clean()``, ``delete()``, ... Bref, toutes les méthodes qui font qu'une instance est sait **comment** interagir avec la base de données. La base d'un `ORM `_, en fait. + +D'autre part, chaque classe héritant de ``models.Model`` possède une propriété ``objects``. Comme on l'a vu dans la section **Jouons un peu avec la console**, cette propriété permet d'accéder aux objects persistants dans la base de données. diff --git a/source/models/user-management.rst b/source/models/user-management.rst index 615651a..f6fc4b5 100644 --- a/source/models/user-management.rst +++ b/source/models/user-management.rst @@ -3,4 +3,3 @@ Gestion des utilisateurs ************************ Dans les spécifications, nous souhaitions pouvoir associer un utilisateur à une liste (*le propriétaire*) et un utilisateur à une part (*le donateur*). Par défaut, Django offre une gestion simplifiée des utilisateurs (pas de connexion LDAP, pas de double authentification, ...): juste un utilisateur et un mot de passe. Pour y accéder, un paramètre par défaut est défini dans votre fichier de settings: ``AUTH_USER_MODEL``. -