0

I'm using Pyramid to build a webapp, and I've got two views where one leads to the other:

config.add_route("new", "/workflow/new")
config.add_route("next", "/workflow/{id}/next")

The new view is really very simple and presents only an HTML form as a Jinja2 template for the user to fill in some information:

<form method="post" action="{{ request.route_url('next',id='') }}" >
  <input type="text" name="id" value="Identifier" />
  ...
  <input type="submit" name="next" value="Next" />
</form>

The question here regards the action of that form: how can I use the content of the text input field id, perhaps process it a little, and then pass it on in the route request?

Note that in this scenario the form data is passed from the new view to the next view, and that should stay the same.

Jens
  • 8,423
  • 9
  • 58
  • 78

1 Answers1

0

When the form is posted, the forms fields will be available in the request object, see http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/webob.html#request

I believe it is also a good idea to post to the same url (<form action="#" method="post">), so that you can validate the form. Then you can process and redirect to the next url when the form is valid, or recreate the form with errors if it isn't.

So your view may end up something like this;

from pyramid.httpexceptions import HTTPFound
from pyramid.url import route_url

def myview(request):

    if request.method == 'POST':
        # Validate the form data
        if <form validates successfully>:
            # Do any processing and saving here.
            return HTTPFound(location = route_url('next', id=request.params['id'], request=self.request))
        else:
            request.session.flash("The form isn't valid.")

    # Do some stuff here to re-populate your form with the request.params

    return { # globals for rendering your form }

There are already many questions/answers addressing this, such as How can I redirect after POST in Pyramid?

Community
  • 1
  • 1
neRok
  • 995
  • 9
  • 21
  • That [`HTTPFound()`](http://docs.pylonsproject.org/docs/pyramid/en/latest/api/httpexceptions.html#pyramid.httpexceptions.HTTPFound) exception invokes the Jinja2 renderer for the next route correctly? – Jens Nov 05 '14 at 00:58
  • It is pretty much a redirect to a new URL, and hence that URLs view callable will be run. – neRok Nov 05 '14 at 01:13
  • How can I then (re)post the form content to the `next` view as part of that HTTPFound request? Just setting .POST didn't quite work, and without it I receive a `Not a form request` within the `next` view; the next view needs to see that data also. (Edited question.) – Jens Nov 05 '14 at 02:05
  • Would the solution be so much different to repost the form data as well, using the approach you've described? – Jens Nov 05 '14 at 02:51
  • I don't know if re-posting is possible (I'm quite new to pyramid too). The following URL indicates HTTPFound uses a GET method. http://docs.pylonsproject.org/docs/pyramid/en/latest/_modules/pyramid/httpexceptions.html#HTTPFound – neRok Nov 05 '14 at 02:56
  • Here are some thoughts (wouldn't fit in previous comment). When you submit "new" (to whatever URL), it will either have a manually entered ID, or an ID will be created in the view callable. Regardless, when the empty "new" view is created on GET, you won't be able to create a URL that contains the ID, as it hasn't been created yet. If its a manual ID, you could change the form action with javascript. Another option is to POST to a view at '/workflow/next' (doesn't use the ID). Another is to use my original answer, but pass the rest of the form as query parameters. – neRok Nov 05 '14 at 02:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64277/discussion-between-nerok-and-jens). – neRok Nov 05 '14 at 03:13
  • FWIW, there's a request.invoke_subrequest() that you can call with a manufactured request object (you can add the POST data to the manufactured request object). – Chris McDonough Nov 05 '14 at 17:09