Read Programming Python Online

Authors: Mark Lutz

Tags: #COMPUTERS / Programming Languages / Python

Programming Python (154 page)

BOOK: Programming Python
9.01Mb size Format: txt, pdf, ePub
ads
Adding Common Input Devices

So far, we’ve been typing
inputs into text fields. HTML forms support a handful of
input controls (what we’d call widgets in the traditional GUI world) for
collecting user inputs. Let’s look at a CGI program that shows all the
common input controls at once. As usual, we define both an HTML file to
lay out the form page and a Python CGI script to process its inputs and
generate a response. The HTML file is presented in
Example 15-11
.

Example 15-11. PP4E\Internet\Web\tutor5a.html

CGI 101

Common input devices





Please complete the following form and click Send









Name:

Shoe size:

Small
Medium
Large

Occupation:

Political affiliations:

Pythonista
Perlmonger
Tcler

Comments:








When rendered by a browser, the page in
Figure 15-13
appears.

Figure 15-13. Input form page generated by tutor5a.html

This page contains a simple text field as before, but it also has
radio buttons, a pull-down selection list, a set of multiple-choice
check buttons, and a multiple-line text input area. All have a
name
option in the HTML file, which identifies
their selected value in the data sent from client to server. When we
fill out this form and click the Send submit button, the script in
Example 15-12
runs on the server to
process all the input data typed or selected in the form.

Example 15-12. PP4E\Internet\Web\cgi-bin\tutor5.py

#!/usr/bin/python
"""
runs on the server, reads form input, prints HTML
"""
import cgi, sys
form = cgi.FieldStorage() # parse form data
print("Content-type: text/html") # plus blank line
html = """
tutor5.py

Greetings




Your name is %(name)s


You wear rather %(shoesize)s shoes


Your current job: %(job)s


You program in %(language)s


You also said:


%(comment)s



"""
data = {}
for field in ('name', 'shoesize', 'job', 'language', 'comment'):
if not field in form:
data[field] = '(unknown)'
else:
if not isinstance(form[field], list):
data[field] = form[field].value
else:
values = [x.value for x in form[field]]
data[field] = ' and '.join(values)
print(html % data)

This Python script doesn’t do much; it mostly just copies form
field information into a dictionary called
data
so that it can be easily inserted into
the triple-quoted response template string. A few of its techniques
merit explanation:

Field validation

As usual, we need to check all expected fields to see
whether they really are present in the input data, using the
dictionary
in
expression. Any
or all of the input fields may be missing if they weren’t entered
on the form or appended to an explicit URL.

String formatting

We’re using dictionary key references in the format string
this time—recall that
%(name)s
means pull out the value for the key
name
in the data dictionary and perform
a to-string conversion on its value.

Multiple-choice fields

We’re also testing the type of all the expected fields’
values to see whether they arrive as a list rather than the usual
string. Values of multiple-choice input controls, like the
language
choice field in this
input page, are returned from
cgi
.
Field
Storage
as a
list of objects with
value
attributes, rather than a simple
single object with a
value
.

This script copies simple field values to the dictionary
verbatim, but it uses a list comprehension to collect the value
fields of multiple-choice selections, and the string
join
method to construct a single string
with an
and
inserted between
each selection value (e.g.,
Python and
Tcl
). The script’s list comprehension is equivalent to
the call
map(lambda x: x.value,
form[field])
.

Not shown here, the
FieldStorage
object’s alternative methods
getfirst
and
getlist
can also be used to treat fields as
single and multiple items, whether they were sent that way or not (see
Python’s library manuals). And as we’ll see later, besides simple
strings and lists, a
third
type of form input
object is returned for fields that specify file uploads. To be robust,
the script should really also escape the echoed text inserted into the
HTML reply, lest it contain HTML operators; we will discuss escapes in
detail later.

When the form page is filled out and submitted, the script creates
the response
shown in
Figure 15-14
—essentially just a
formatted echo of what was sent.

Figure 15-14. Response page created by tutor5.py (1)

Changing Input Layouts

Suppose that you’ve written a
system like that in the prior section, and your users,
clients, and significant other start complaining that the input form is
difficult to read. Don’t worry. Because the CGI model naturally
separates the
user interface
(the HTML input page
definition) from the
processing logic
(the CGI
script), it’s completely painless to change the form’s layout. Simply
modify the HTML file; there’s no need to change the CGI code at all. For
instance,
Example 15-13
contains
a new definition of the input that uses tables a bit differently to
provide a nicer layout with borders.

Example 15-13. PP4E\Internet\Web\tutor5b.html

CGI 101

Common input devices: alternative layout


Use the same tutor5.py server side script, but change the
layout of the form itself. Notice the separation of user interface
and processing logic here; the CGI script is independent of the
HTML used to interact with the user/client.




Please complete the following form and click Submit









Name:

Shoe size:
Small
Medium
Large
Occupation:

Political affiliations:

Pythonista

Perlmonger

Tcler

Comments:







When we visit this alternative page with a browser, we get the
interface shown in
Figure 15-15
.

Figure 15-15. Form page created by tutor5b.html

Now, before you go blind trying to detect the differences in this
and the prior HTML file, I should note that the HTML differences that
produce this page are much less important for this book than the fact
that the
action
fields in these two
pages’ forms reference identical URLs. Pressing this version’s Submit
button triggers the exact same and totally unchanged Python CGI script
again,
tutor5.py
(
Example 15-12
).

That is, scripts are completely independent of both the
transmission mode (URL query parameters of form fields) and the layout
of the user interface used to send them information. Changes in the
response page require changing the script, of course, because the HTML
of the reply page is still embedded in the CGI script. But we can change
the input page’s HTML as much as we like without affecting the
server-side Python code.
Figure 15-16
shows the response
page produced by the script this time around.

Figure 15-16. Response page created by tutor5.py (2)

Keeping display and logic separate

In fact, this illustrates
an important point in the design of larger websites: if
we are careful to keep the HTML and script code separate, we get a
useful division of display and logic—each part can be worked on
independently, by people with different skill sets. Web page
designers, for example, can work on the display layout, while
programmers can code business logic.

Although this section’s example is fairly small, it already
benefits from this separation for the input page. In some cases, the
separation is harder to accomplish, because our example scripts embed
the HTML of reply pages. With just a little more work, though, we can
usually split the reply HTML off into separate files that can also be
developed independently of the script’s logic. The
html
string in
tutor5.py
(
Example 15-12
), for instance, might
be stored in a text file and loaded by the script when run.

In larger systems, tools such as server-side HTML templating
languages help make the division of display and logic even easier to
achieve. The
Python Server Pages system and frameworks such as Zope
and Django,
for instance, promote the separation of display and
logic by providing reply page description languages that are expanded
to include portions generated by separate Python program logic. In a
sense, server-side templating languages embed Python in HTML—the
opposite of CGI scripts that embed HTML in Python—and may provide a
cleaner division of labor, provided the Python code is separate
components. Search the Web for more details. Similar techniques can be
used for separation of layout and login in the GUIs we studied earlier
in this book, but they also usually require larger frameworks or
models to
achieve.

BOOK: Programming Python
9.01Mb size Format: txt, pdf, ePub
ads

Other books

What's Left of Her by Mary Campisi
Love on the Malecon by Aubrey Parr
The Secret of Lions by Scott Blade
The Headstrong Ward by Jane Ashford
The Ice Marathon by Rosen Trevithick