1 .. -*- coding: utf-8 -*- |
|
2 |
|
3 Paramétrages et extensions spécifiques |
|
4 -------------------------------------- |
|
5 |
|
6 Valeurs par défaut dynamiques |
|
7 ````````````````````````````` |
|
8 Il est possible de définir dans le schéma des valeurs par défaut *statiques*. |
|
9 Il est également possible de définir des valeurs par défaut *dynamiques* en |
|
10 définissant sur la classe d'entité une méthode `default_<nom attribut>` pour |
|
11 un attribut donnée. |
|
12 |
|
13 |
|
14 Contrôle des attributs chargés et du tri par défaut |
|
15 ``````````````````````````````````````````````````` |
|
16 * l'attribut de classe `fetch_attrs` permet de définir sur une classe d'entité |
|
17 la liste des noms des attributs ou relations devant être chargés |
|
18 automatiquement lors de la récupération d'entité(s) de ce type. Dans le cas |
|
19 des relations, on est limité aux relations *sujets de cardinalité `?` ou `1`*. |
|
20 |
|
21 * la méthode de classe `fetch_order(attr, var)` prend en argument un nom |
|
22 d'attribut (ou de relation) et un nom de variable et doit retourner une chaine |
|
23 à utiliser dans la close "ORDERBY" d'une requête RQL pour trier |
|
24 automatiquement les listes d'entités de ce type selon cet attribut, ou `None` |
|
25 si l'on ne veut pas de tri sur l'attribut passé en argument. Par défaut les |
|
26 entités sont triées selon leur date de création |
|
27 |
|
28 * la méthode de classe `fetch_unrelated_order(attr, var)` est similaire à la |
|
29 méthode `fetch_order` mais est utilisée essentiellement pour contrôler le tri |
|
30 des listes déroulantes permettant de créer des relations dans la vue d'édition |
|
31 d'une entité |
|
32 |
|
33 La fonction `fetch_config(fetchattrs, mainattr=None)` permet de simplifier la |
|
34 définition des attributs à précharger et du tri en retournant une liste des |
|
35 attributs à précharger (en considérant ceux de la classe `AnyEntity` |
|
36 automatiquement) et une fonction de tri sur l'attribut "principal" (le 2eme |
|
37 argument si spécifié ou sinon le premier attribut de la liste `fetchattrs`). |
|
38 Cette fonction est définie dans le package `ginco.entities`. |
|
39 |
|
40 Par exemple : :: |
|
41 |
|
42 class Transition(AnyEntity): |
|
43 """...""" |
|
44 id = 'Transition' |
|
45 fetch_attrs, fetch_order = fetch_config(['name']) |
|
46 |
|
47 Indique que pour le type d'entité "Transition" il faut précharger l'attribut |
|
48 "name" et trier par défaut selon cet attribut. |
|
49 |
|
50 |
|
51 Contrôle des formulaires d'édition |
|
52 `````````````````````````````````` |
|
53 Il est possible de contrôler les attributs/relations dans la vue d'édition |
|
54 simple ou multiple à l'aide des *rtags* suivants : |
|
55 |
|
56 * `primary`, indique qu'un attribut ou une relation doit être incorporé dans |
|
57 les formulaires d'édition simple et multiple. Dans le cas d'une relation, |
|
58 le formulaire d'édition de l'entité liée sera inclus dans le formulaire |
|
59 |
|
60 * `secondary`, indique qu'un attribut ou une relation doit être incorporé dans |
|
61 le formulaire d'édition simple uniquement. Dans le cas d'une relation, |
|
62 le formulaire d'édition de l'entité liée sera inclus dans le formulaire |
|
63 |
|
64 * `generic`, indique qu'une relation doit être incorporé dans le formulaire |
|
65 d'édition simple dans la boite générique d'ajout de relation |
|
66 |
|
67 * `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et |
|
68 qu'il ne doit donc pas être présent dans les formulaires d'édition |
|
69 |
|
70 Au besoin il est possible de surcharger la méthode |
|
71 `relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie |
|
72 d'édition d'une relation. |
|
73 |
|
74 |
|
75 Contrôle de la boîte "add_related" |
|
76 `````````````````````````````````` |
|
77 La boite `add related` est une boite automatique proposant de créer une entité |
|
78 qui sera automatiquement liée à l'entité de départ (le contexte dans lequel |
|
79 s'affiche la boite). Par défaut, les liens présents dans cette boite sont |
|
80 calculés en fonction des propriétés du schéma de l'entité visualisée, mais il |
|
81 est possible de les spécifier explicitement à l'aide des *rtags* suivants : |
|
82 |
|
83 * `link`, indique qu'une relation est généralement créée vers une entité |
|
84 existante et qu'il ne faut donc pas faire apparaitre de lien pour cette |
|
85 relation |
|
86 |
|
87 * `create`, indique qu'une relation est généralement créée vers de nouvelles |
|
88 entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle |
|
89 entité et la lier automatiquement |
|
90 |
|
91 Au besoin il est possible de surcharger la méthode |
|
92 `relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la |
|
93 catégorie de création d'une relation. |
|
94 |
|
95 A noter également que si au moins une action dans la catégorie "addrelated" est |
|
96 trouvée pour le contexte courant, le fonctionnement automatique est désactivé |
|
97 en faveur du fonctionnement explicite (i.e. affichage des actions de la |
|
98 catégorie "addrelated" uniquement). |
|
99 |
|
100 Contrôle des formulaires de filtrage de table |
|
101 ````````````````````````````````````````````` |
|
102 La vue "table" par défaut gère dynamiquement un formulaire de filtrage du |
|
103 contenu de celle-ci. L'algorithme est le suivant : |
|
104 |
|
105 1. on considère que la première colonne contient les entités à restreindre |
|
106 2. on recupère la première entité de la table (ligne 0) pour "représenter" |
|
107 toutes les autres |
|
108 3. pour toutes les autres variables définies dans la requête originale : |
|
109 |
|
110 1. si la variable est liée à la variable principale par au moins une |
|
111 n'importe quelle relation |
|
112 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité |
|
113 et si rien est retourné (ou plus exactement un tuple de valeur `None`, |
|
114 voir ci-dessous) on passe à la variable suivante, sinon un élément de |
|
115 formulaire de filtrage sera créé avec les valeurs de vocabulaire |
|
116 retournées |
|
117 |
|
118 4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses |
|
119 de tris, de groupes... Des fonctions javascripts sont utilisées pour |
|
120 regénérer une requête à partir de la requête de départ et des valeurs |
|
121 séléctionnées dans les filtres de formulaire. |
|
122 |
|
123 |
|
124 La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend |
|
125 en argument le nom d'une relation et la "cible", qui indique si l'entité sur |
|
126 laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit |
|
127 retourner : |
|
128 |
|
129 * un 2-uple de None si elle ne sait pas gérer cette relation |
|
130 |
|
131 * un type et une liste contenant le vocabulaire |
|
132 |
|
133 * la liste doit contenir des couples (valeur, label) |
|
134 * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une |
|
135 chaîne de caractères (`type == 'string'`) ou une entité non finale (`type |
|
136 == 'eid'`) |
|
137 |
|
138 Par exemple dans notre application de gestion de tickets, on veut pouvoir |
|
139 filtrés ceux-ci par : |
|
140 |
|
141 * type |
|
142 * priorité |
|
143 * état (in_state) |
|
144 * étiquette (tags) |
|
145 * version (done_in) |
|
146 |
|
147 On définit donc la méthode suivante : :: |
|
148 |
|
149 |
|
150 class Ticket(AnyEntity): |
|
151 |
|
152 ... |
|
153 |
|
154 def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey): |
|
155 _ = self.req._ |
|
156 if rtype == 'type': |
|
157 return 'string', [(x, _(x)) for x in ('bug', 'story')] |
|
158 if rtype == 'priority': |
|
159 return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')] |
|
160 if rtype == 'done_in': |
|
161 rql = insert_attr_select_relation(rqlst, var, rtype, 'num') |
|
162 return 'eid', self.req.execute(rql, args, cachekey) |
|
163 return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst, |
|
164 args, cachekey) |
|
165 |
|
166 |
|
167 NOTE: Le support du filtrage sur les étiquettes et l'état est installé |
|
168 automatiquement, pas besoin de le gérer ici. |
|