sutee
sutee

Reputation: 12828

Better way of passing form parameters into hidden form in Pyramid

In a previous question, I was trying to figure out the right strategy for to passing data between forms in Pyramid. Based on the answer I received, I decided the approach of using a hidden form.

I started implementing this and think there must be a better way of passing along the data. Specifically, passing parameters through the url results in a tuple that is messy to parse.

I want it to be general enough to not to know what parameters the form has and also it needs to handle file fields as well.

How I'm currently attempting to pass the form data to the confirmation page:

@view_config(renderer="templates/derived/load/error.mak", route_name='process_model_route')
def process_model(self):
    #processing logic and validaton, failiure in validation sends user to error.mak
    return HTTPFound(route_url('confirm_model_route', self.request, fparams=self.request.POST))

Route: config.add_route('confirm_model_route', 'rnd2/model/confirm/*fparams')

@view_config(renderer="templates/derived/confirm/model.mak", route_name='confirm_model_route')
def confirm_model(self):
    form_dict = self.request.matchdict['fparams']
     #need to decode and pass to template
     return dict({'load_route':load_route, 'form_dict':form_dict})

The confirm/model.mak template would contain the hidden form.

Upvotes: 1

Views: 817

Answers (1)

Michael Merickel
Michael Merickel

Reputation: 23331

The idea with this method is:

  1. Client visits page.
  2. Server renders the form.
  3. Client fills in form and POSTs to URL.
  4. Server renders a new page that contains a hidden form with all of the data it just received in the POST.
  5. Client POSTs to a URL, confirming the submission.
  6. Server persists the data from the hidden form and redirects.

Now depending on usability, it's up to you to decide how many different URLs you actually want here and how many views in Pyramid. You have to think about what happens with invalid data?

Notice in the outline above, once the user POSTs the form to a URL, that URL must return the confirmation page containing a hidden form. If you try to redirect the user to a confirmation page instead, you must persist the data somehow, either in a session or through the hack you showed in your example (shoving all of the data into the GET). The second solution is very bad because it abuses the true purpose of GET in HTTP.

There is also the convention that every POST should result in a redirect to avoid a client submitting the form multiple times. With this in mind you might consider the simple solution of rejecting POSTs that do not have a "confirmed" flag and simply setting the "confirmed" flag in javascript after prompting the user. This allows you to keep your form handling logic simple.

If you don't want to rely on javascript and you don't want to persist the form data in a session, then you run into the issue of not redirecting after the first POST but other than that it should be simple from the outline above.

Upvotes: 4

Related Questions