#19189: FormWizard done method can't revisit forms
-----------------------------------+--------------------------------------
     Reporter:  kenth              |                    Owner:  nobody
         Type:  New feature        |                   Status:  reopened
    Component:  contrib.formtools  |                  Version:  master
     Severity:  Normal             |               Resolution:
     Keywords:                     |             Triage Stage:  Unreviewed
    Has patch:  1                  |      Needs documentation:  0
  Needs tests:  0                  |  Patch needs improvement:  0
Easy pickings:  0                  |                    UI/UX:  0
-----------------------------------+--------------------------------------
Changes (by kenth):

 * status:  closed => reopened
 * has_patch:  0 => 1
 * resolution:  needsinfo =>


Comment:

 Thanks for reviewing the ticket. I found the need to perform
 "revalidation" in the `done` step in an e-commerce project incorporating
 validation using stripe.com which separates validation (performed in the
 form's `clean` method) and charging (which I perform in `done`). However,
 I think the problem is more general than this specific case.

 I had rejected performing a 'charge' in the clean of a confirmation step,
 instead preferring the `done` method for two reasons:

 1. The wizard validates each form at least twice (when the form is
 initially validated and again in `render_done`). To ensure an action is
 performed only once, the `clean` method needs to leave a token to not
 repeat the action. This can be fragile.

 2. The wizard does not revalidate earlier steps when first validating a
 form. Thus, if a confirmation step's `clean` charges when first validated,
 and an earlier step's form fails revalidation in `render_done` (say stock
 on an item is no longer available, or a discount window has expired), the
 charge has already occurred and the `done` step will not be processed. The
 transaction is a mess at that point.

 An alternate solution would be to have earlier forms check if the charge
 has occurred and always return `valid()` in that case. I'm not sure how
 that would interact with tampering detection and the like.

 Accordingly actions which must not be duplicated are best performed in the
 `done` method. The `done` method guarantees all forms validate & the
 wizard state is deleted upon completion. The current wizard allows for
 forms which do not revalidate, but does not allow for a `done` method
 which may not complete successfully. The proposed exception handles this
 case.

 An implementation I currently use defines the `Exception` in my wizard
 subclass & then overrides `render_done` to catch the exception and step
 back into the `FormWizard` as needed. Django being open-source and Python,
 the workaround is quite functional. However I thought the problem and
 solution general enough for inclusion.

 I have attached a patch w/ tests. I can work up the docs if it would help.

 Thanks. Kent

-- 
Ticket URL: <https://code.djangoproject.com/ticket/19189#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to