103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
104 |
104 |
105 When called for one of these events, hook will have an `entity` attribute |
105 When called for one of these events, hook will have an `entity` attribute |
106 containing the entity instance. |
106 containing the entity instance. |
107 |
107 |
108 * `before_add_entity`, `before_update_entity`: |
108 - `before_add_entity`, `before_update_entity`: |
109 |
109 |
110 - on those events, you can check what attributes of the entity are modified in |
110 On those events, you can access the modified attributes of the entity using |
111 `entity.cw_edited` (by definition the database is not yet updated in a before |
111 the `entity.cw_edited` dictionnary. The values can be modified and the old |
112 event) |
112 values can be retrieved. |
113 |
113 |
114 - you are allowed to further modify the entity before database |
114 If you modify the `entity.cw_edited` dictionnary in the hook, that is before |
115 operations, using the dictionary notation on `cw_edited`. By doing |
115 the database operations take place, you will avoid the need to process a whole |
116 this, you'll avoid the need for a whole new rql query processing, |
116 new rql query and the underlying backend query (eg usually sql) will contain |
117 the only difference is that the underlying backend query (eg |
117 the modified data. For example: |
118 usually sql) will contains the additional data. For example: |
118 |
119 |
119 .. sourcecode:: python |
120 .. sourcecode:: python |
120 |
121 |
121 self.entity.cw_edited['age'] = 42 |
122 self.entity.set_attributes(age=42) |
122 |
123 |
123 will modify the age before it is written to the backend storage. |
124 will set the `age` attribute of the entity to 42. But to do so, it will |
124 |
125 generate a rql query that will have to be processed, then trigger some |
125 Similarly, removing an attribute from `cw_edited` will cancel its |
126 hooks, and so one (potentially leading to infinite hook loops or such |
126 modification: |
127 awkward situations..) You can avoid this by doing the modification that way: |
127 |
128 |
128 .. sourcecode:: python |
129 .. sourcecode:: python |
129 |
130 |
130 del self.entity.cw_edited['age'] |
131 self.entity.cw_edited['age'] = 42 |
131 |
132 |
132 On a `before_update_entity` event, you can access the old and new values: |
133 Here the attribute will simply be edited in the same query that the |
133 |
134 one that triggered the hook. |
134 .. sourcecode:: python |
135 |
135 |
136 Similarly, removing an attribute from `cw_edited` will cancel its |
136 old, new = entity.cw_edited.oldnewvalue('age') |
137 modification. |
137 |
138 |
138 - `after_add_entity`, `after_update_entity` |
139 - on `before_update_entity` event, you can access to old and new values in |
139 |
140 this hook, by using `entity.cw_edited.oldnewvalue(attr)` |
140 On those events, you can get the list of attributes that were modified using |
141 |
141 the `entity.cw_edited` dictionnary, but you can not modify it or get the old |
142 |
142 value of an attribute. |
143 * `after_add_entity`, `after_update_entity` |
143 |
144 |
144 - `before_delete_entity`, `after_delete_entity` |
145 - on those events, you can still check what attributes of the entity are |
145 |
146 modified in `entity.cw_edited` but you can't get anymore the old value, nor |
146 On those events, the entity has no `cw_edited` dictionnary. |
147 modify it. |
147 |
148 |
148 .. note:: `self.entity.set_attributes(age=42)` will set the `age` attribute to |
149 * `before_delete_entity`, `after_delete_entity` |
149 42. But to do so, it will generate a rql query that will have to be processed, |
150 |
150 hence may trigger some hooks, etc. This could lead to infinitely looping hooks. |
151 - on those events, the entity has no `cw_edited` set. |
|
152 |
|
153 |
151 |
154 Relation modification related events |
152 Relation modification related events |
155 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
153 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
156 |
154 |
157 When called for one of these events, hook will have `eidfrom`, `rtype`, `eidto` |
155 When called for one of these events, hook will have `eidfrom`, `rtype`, `eidto` |
158 attributes containing respectivly the eid of the subject entity, the relation |
156 attributes containing respectively the eid of the subject entity, the relation |
159 type and the eid of the object entity. |
157 type and the eid of the object entity. |
160 |
158 |
161 * `before_add_relation`, `before_delete_relation` |
159 * `before_add_relation`, `before_delete_relation` |
162 |
160 |
163 - on those events, you can still get original relation by issuing a rql query |
161 On those events, you can still get the original relation by issuing a rql query. |
164 |
162 |
165 * `after_add_relation`, `after_delete_relation` |
163 * `after_add_relation`, `after_delete_relation` |
166 |
164 |
167 This is an occasion to remind us that relations support the add / delete |
165 Take note that relations can be added or deleted, but not updated. |
168 operation, but no update. |
|
169 |
|
170 |
166 |
171 Non data events |
167 Non data events |
172 ~~~~~~~~~~~~~~~ |
168 ~~~~~~~~~~~~~~~ |
173 |
169 |
174 Hooks called on server start/maintenance/stop event (eg `server_startup`, |
170 Hooks called on server start/maintenance/stop event (eg `server_startup`, |