change forms

This commit is contained in:
Fred Pauchet 2016-04-13 16:08:38 +02:00
parent faa6ffbb9d
commit 1325f1851d
6 changed files with 36 additions and 10 deletions

View File

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

View File

@ -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 <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.
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, ...)'
})

View File

@ -47,3 +47,4 @@ Les classes sont créées, mais vides. Entrons dans les détails.
.. include:: models/console.rst
.. include:: models/metamodel.rst

View File

@ -92,5 +92,3 @@ A partir de maintenant, on peut accéder à nos propriétés de la manière suiv
[<Item: Item object>]
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``.

View File

@ -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 <https://pypi.python.org/pypi/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 <https://en.wikipedia.org/wiki/Object-relational_mapping>`_, 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.

View File

@ -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``.