2 Bonus Tutorial: Using SQLObject
4 This is a silly little contacts manager application intended to
5 demonstrate how to use SQLObject from within a CherryPy2 project. It
6 also shows how to use inline Cheetah templates.
8 SQLObject is an Object/Relational Mapper that allows you to access
9 data stored in an RDBMS in a pythonic fashion. You create data objects
10 as Python classes and let SQLObject take care of all the nasty details.
12 This code depends on the latest development version (0.6+) of SQLObject.
13 You can get it from the SQLObject Subversion server. You can find all
14 necessary information at <http://www.sqlobject.org>. This code will NOT
15 work with the 0.5.x version advertised on their website!
17 This code also depends on a recent version of Cheetah. You can find
18 Cheetah at <http://www.cheetahtemplate.org>.
20 After starting this application for the first time, you will need to
21 access the /reset URI in order to create the database table and some
22 sample data. Accessing /reset again will drop and re-create the table,
23 so you may want to be careful. :-)
25 This application isn't supposed to be fool-proof, it's not even supposed
26 to be very GOOD. Play around with it some, browse the source code, smile.
30 -- Hendrik Mans <hendrik@mans.de>
34 from Cheetah
.Template
import Template
35 from sqlobject
import *
37 # configure your database connection here
38 __connection__
= 'mysql://root:@localhost/test'
40 # this is our (only) data class.
41 class Contact(SQLObject
):
42 lastName
= StringCol(length
= 50, notNone
= True)
43 firstName
= StringCol(length
= 50, notNone
= True)
44 phone
= StringCol(length
= 30, notNone
= True, default
= '')
45 email
= StringCol(length
= 30, notNone
= True, default
= '')
46 url
= StringCol(length
= 100, notNone
= True, default
= '')
51 # Let's display a list of all stored contacts.
52 contacts
= Contact
.select()
54 template
= Template('''
57 #for $contact in $contacts
58 <a href="mailto:$contact.email">$contact.lastName, $contact.firstName</a>
59 [<a href="./edit?id=$contact.id">Edit</a>]
60 [<a href="./delete?id=$contact.id">Delete</a>]
64 <p>[<a href="./edit">Add new contact</a>]</p>
65 ''', [locals(), globals()])
67 return template
.respond()
72 def edit(self
, id = 0):
73 # we really want id as an integer. Since GET/POST parameters
74 # are always passed as strings, let's convert it.
78 # if an id is specified, we're editing an existing contact.
79 contact
= Contact
.get(id)
80 title
= "Edit Contact"
82 # if no id is specified, we're entering a new contact.
87 # In the following template code, please note that we use
88 # Cheetah's $getVar() construct for the form values. We have
89 # to do this because contact may be set to None (see above).
90 template
= Template('''
93 <form action="./store" method="POST">
94 <input type="hidden" name="id" value="$id" />
95 Last Name: <input name="lastName" value="$getVar('contact.lastName', '')" /><br/>
96 First Name: <input name="firstName" value="$getVar('contact.firstName', '')" /><br/>
97 Phone: <input name="phone" value="$getVar('contact.phone', '')" /><br/>
98 Email: <input name="email" value="$getVar('contact.email', '')" /><br/>
99 URL: <input name="url" value="$getVar('contact.url', '')" /><br/>
100 <input type="submit" value="Store" />
102 ''', [locals(), globals()])
104 return template
.respond()
109 def delete(self
, id):
110 # Delete the specified contact
111 contact
= Contact
.get(int(id))
112 contact
.destroySelf()
113 return 'Deleted. <a href="./">Return to Index</a>'
115 delete
.exposed
= True
118 def store(self
, lastName
, firstName
, phone
, email
, url
, id = None):
119 if id and int(id) > 0:
120 # If an id was specified, update an existing contact.
121 contact
= Contact
.get(int(id))
123 # We could set one field after another, but that would
124 # cause multiple UPDATE clauses. So we'll just do it all
125 # in a single pass through the set() method.
128 firstName
= firstName
,
133 # Otherwise, add a new contact.
136 firstName
= firstName
,
141 return 'Stored. <a href="./">Return to Index</a>'
147 # Drop existing table
148 Contact
.dropTable(True)
151 Contact
.createTable()
153 # Create some sample data
155 firstName
= 'Hendrik',
157 email
= 'hendrik@mans.de',
158 phone
= '++49 89 12345678',
159 url
= 'http://www.mornography.de')
161 return "reset completed!"
166 print("If you're running this application for the first time, please go to http://localhost:8080/reset once in order to create the database!")
168 cherrypy
.quickstart(ContactManager())