185 # so we're able to know the main entity from the repository side |
185 # so we're able to know the main entity from the repository side |
186 if '__maineid' in form: |
186 if '__maineid' in form: |
187 req.transaction_data['__maineid'] = form['__maineid'] |
187 req.transaction_data['__maineid'] = form['__maineid'] |
188 # no specific action, generic edition |
188 # no specific action, generic edition |
189 self._to_create = req.data['eidmap'] = {} |
189 self._to_create = req.data['eidmap'] = {} |
190 # those two data variables are used to handle relation from/to entities |
190 # those three data variables are used to handle relation from/to entities |
191 # which doesn't exist at time where the entity is edited and that |
191 # which doesn't exist at time where the entity is edited and that |
192 # deserves special treatment |
192 # deserves special treatment |
193 req.data['pending_inlined'] = defaultdict(set) |
193 req.data['pending_inlined'] = defaultdict(set) |
194 req.data['pending_others'] = set() |
194 req.data['pending_others'] = set() |
195 req.data['pending_composite_delete'] = set() |
195 req.data['pending_composite_delete'] = set() |
|
196 req.data['pending_values'] = dict() |
196 try: |
197 try: |
197 for formparams in self._ordered_formparams(): |
198 for formparams in self._ordered_formparams(): |
198 self.edit_entity(formparams) |
199 self.edit_entity(formparams) |
199 except (RequestError, NothingToEdit) as ex: |
200 except (RequestError, NothingToEdit) as ex: |
200 if '__linkto' in req.form and 'eid' in req.form: |
201 if '__linkto' in req.form and 'eid' in req.form: |
203 raise ValidationError(None, {None: text_type(ex)}) |
204 raise ValidationError(None, {None: text_type(ex)}) |
204 # all pending inlined relations to newly created entities have been |
205 # all pending inlined relations to newly created entities have been |
205 # treated now (pop to ensure there are no attempt to add new ones) |
206 # treated now (pop to ensure there are no attempt to add new ones) |
206 pending_inlined = req.data.pop('pending_inlined') |
207 pending_inlined = req.data.pop('pending_inlined') |
207 assert not pending_inlined, pending_inlined |
208 assert not pending_inlined, pending_inlined |
|
209 pending_values = req.data.pop('pending_values') |
208 # handle all other remaining relations now |
210 # handle all other remaining relations now |
209 while req.data['pending_others']: |
211 while req.data['pending_others']: |
210 form_, field = req.data['pending_others'].pop() |
212 form_, field = req.data['pending_others'].pop() |
211 self.handle_formfield(form_, field) |
213 # attempt to retrieve values and original values if they have already gone through |
|
214 # handle_formfield (may not if there has been some not yet known eid at the first |
|
215 # processing round). In the later case we've to go back through handle_formfield. |
|
216 try: |
|
217 values, origvalues = pending_values.pop((form_, field)) |
|
218 except KeyError: |
|
219 self.handle_formfield(form_, field) |
|
220 else: |
|
221 self.handle_relation(form_, field, values, origvalues) |
|
222 assert not pending_values, 'unexpected remaining pending values %s' % pending_values |
212 del req.data['pending_others'] |
223 del req.data['pending_others'] |
213 # then execute rql to set all relations |
224 # then execute rql to set all relations |
214 for querydef in self.relations_rql: |
225 for querydef in self.relations_rql: |
215 self._cw.execute(*querydef) |
226 self._cw.execute(*querydef) |
216 # delete pending composite |
227 # delete pending composite |
328 self.handle_inlined_relation(form, field, value, origvalues, rqlquery) |
339 self.handle_inlined_relation(form, field, value, origvalues, rqlquery) |
329 elif form.edited_entity.has_eid(): |
340 elif form.edited_entity.has_eid(): |
330 self.handle_relation(form, field, value, origvalues) |
341 self.handle_relation(form, field, value, origvalues) |
331 else: |
342 else: |
332 form._cw.data['pending_others'].add((form, field)) |
343 form._cw.data['pending_others'].add((form, field)) |
|
344 form._cw.data['pending_values'][(form, field)] = (value, origvalues) |
333 |
345 |
334 except ProcessFormError as exc: |
346 except ProcessFormError as exc: |
335 self.errors.append((field, exc)) |
347 self.errors.append((field, exc)) |
336 |
348 |
337 def handle_composite_removal(self, form, field, |
349 def handle_composite_removal(self, form, field, |