diff options
| author | Casey Duncan <casey.duncan@gmail.com> | 2011-01-03 00:10:04 -0700 |
|---|---|---|
| committer | Casey Duncan <casey.duncan@gmail.com> | 2011-01-03 00:10:04 -0700 |
| commit | 81bd32edadc54928fb84e1a35d7ccd4b34c4dc22 (patch) | |
| tree | dce0446644ad77272a663a414ccee972ad9f78b5 | |
| parent | 245316b0159f75269a1a7a4c5327c712e1475cc2 (diff) | |
| download | pyramid-81bd32edadc54928fb84e1a35d7ccd4b34c4dc22.tar.gz pyramid-81bd32edadc54928fb84e1a35d7ccd4b34c4dc22.tar.bz2 pyramid-81bd32edadc54928fb84e1a35d7ccd4b34c4dc22.zip | |
add placeholder form handling chapt, may move to cookbook
| -rw-r--r-- | docs/index.rst | 1 | ||||
| -rw-r--r-- | docs/latexindex.rst | 1 | ||||
| -rw-r--r-- | docs/narr/forms.rst | 121 |
3 files changed, 123 insertions, 0 deletions
diff --git a/docs/index.rst b/docs/index.rst index fe3cf2ce8..df0bbcd2f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -65,6 +65,7 @@ Narrative documentation in chapter form explaining how to use narr/router narr/threadlocals narr/zca + narr/forms Tutorials ========= diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 608a49678..59ced2ac8 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -59,6 +59,7 @@ Narrative Documentation narr/startup narr/threadlocals narr/zca + narr/forms .. _tutorials: diff --git a/docs/narr/forms.rst b/docs/narr/forms.rst new file mode 100644 index 000000000..9ba862022 --- /dev/null +++ b/docs/narr/forms.rst @@ -0,0 +1,121 @@ +.. _forms_chapter: + +Form Handling +============= + +Handling Form Submissions in View Callables (Unicode and Character Set Issues) +------------------------------------------------------------------------------ + +Most web applications need to accept form submissions from web browsers and +various other clients. In :app:`Pyramid`, form submission handling logic is +always part of a :term:`view`. For a general overview of how to handle form +submission data using the :term:`WebOb` API, see :ref:`webob_chapter` and +`"Query and POST variables" within the WebOb documentation +<http://pythonpaste.org/webob/reference.html#query-post-variables>`_. +:app:`Pyramid` defers to WebOb for its request and response implementations, +and handling form submission data is a property of the request +implementation. Understanding WebOb's request API is the key to +understanding how to process form submission data. + +There are some defaults that you need to be aware of when trying to handle +form submission data in a :app:`Pyramid` view. Having high-order (i.e., +non-ASCII) characters in data contained within form submissions is +exceedingly common, and the UTF-8 encoding is the most common encoding used +on the web for character data. Since Unicode values are much saner than +working with and storing bytestrings, :app:`Pyramid` configures the +:term:`WebOb` request machinery to attempt to decode form submission values +into Unicode from UTF-8 implicitly. This implicit decoding happens when view +code obtains form field values via the ``request.params``, ``request.GET``, +or ``request.POST`` APIs (see :ref:`request_module` for details about these +APIs). + +.. note:: + + Many people find the difference between Unicode and UTF-8 confusing. + Unicode is a standard for representing text that supports most of the + world's writing systems. However, there are many ways that Unicode data + can be encoded into bytes for transit and storage. UTF-8 is a specific + encoding for Unicode, that is backwards-compatible with ASCII. This makes + UTF-8 very convenient for encoding data where a large subset of that data + is ASCII characters, which is largely true on the web. UTF-8 is also the + standard character encoding for URLs. + +As an example, let's assume that the following form page is served up to a +browser client, and its ``action`` points at some :app:`Pyramid` view code: + +.. code-block:: xml + :linenos: + + <html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + </head> + <form method="POST" action="myview"> + <div> + <input type="text" name="firstname"/> + </div> + <div> + <input type="text" name="lastname"/> + </div> + <input type="submit" value="Submit"/> + </form> + </html> + +The ``myview`` view code in the :app:`Pyramid` application *must* expect that +the values returned by ``request.params`` will be of type ``unicode``, as +opposed to type ``str``. The following will work to accept a form post from +the above form: + +.. code-block:: python + :linenos: + + def myview(request): + firstname = request.params['firstname'] + lastname = request.params['lastname'] + +But the following ``myview`` view code *may not* work, as it tries to decode +already-decoded (``unicode``) values obtained from ``request.params``: + +.. code-block:: python + :linenos: + + def myview(request): + # the .decode('utf-8') will break below if there are any high-order + # characters in the firstname or lastname + firstname = request.params['firstname'].decode('utf-8') + lastname = request.params['lastname'].decode('utf-8') + +For implicit decoding to work reliably, you should ensure that every form you +render that posts to a :app:`Pyramid` view explicitly defines a charset +encoding of UTF-8. This can be done via a response that has a +``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form above, +with a ``meta http-equiv`` tag that implies that the charset is UTF-8 within +the HTML ``head`` of the page containing the form. This must be done +explicitly because all known browser clients assume that they should encode +form data in the same character set implied by ``Content-Type`` value of the +response containing the form when subsequently submitting that form. There is +no other generally accepted way to tell browser clients which charset to use +to encode form data. If you do not specify an encoding explicitly, the +browser client will choose to encode form data in its default character set +before submitting it, which may not be UTF-8 as the server expects. If a +request containing form data encoded in a non-UTF8 charset is handled by your +view code, eventually the request code accessed within your view will throw +an error when it can't decode some high-order character encoded in another +character set within form data, e.g., when ``request.params['somename']`` is +accessed. + +If you are using the :class:`pyramid.response.Response` class to generate a +response, or if you use the ``render_template_*`` templating APIs, the UTF-8 +charset is set automatically as the default via the ``Content-Type`` header. +If you return a ``Content-Type`` header without an explicit charset, a +request will add a ``;charset=utf-8`` trailer to the ``Content-Type`` header +value for you, for response content types that are textual +(e.g. ``text/html``, ``application/xml``, etc) as it is rendered. If you are +using your own response object, you will need to ensure you do this yourself. + +.. note:: Only the *values* of request params obtained via + ``request.params``, ``request.GET`` or ``request.POST`` are decoded + to Unicode objects implicitly in the :app:`Pyramid` default + configuration. The keys are still (byte) strings. + + |
