| 1 |
''' |
|---|
| 2 |
Bonus Tutorial: Using SQLObject |
|---|
| 3 |
|
|---|
| 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. |
|---|
| 7 |
|
|---|
| 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. |
|---|
| 11 |
|
|---|
| 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! |
|---|
| 16 |
|
|---|
| 17 |
This code also depends on a recent version of Cheetah. You can find |
|---|
| 18 |
Cheetah at <http://www.cheetahtemplate.org>. |
|---|
| 19 |
|
|---|
| 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. :-) |
|---|
| 24 |
|
|---|
| 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. |
|---|
| 27 |
|
|---|
| 28 |
:) |
|---|
| 29 |
|
|---|
| 30 |
-- Hendrik Mans <hendrik@mans.de> |
|---|
| 31 |
''' |
|---|
| 32 |
|
|---|
| 33 |
import cherrypy |
|---|
| 34 |
from Cheetah.Template import Template |
|---|
| 35 |
from sqlobject import * |
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
__connection__ = 'mysql://root:@localhost/test' |
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 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 = '') |
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
class ContactManager: |
|---|
| 50 |
def index(self): |
|---|
| 51 |
|
|---|
| 52 |
contacts = Contact.select() |
|---|
| 53 |
|
|---|
| 54 |
template = Template(''' |
|---|
| 55 |
<h2>All Contacts</h2> |
|---|
| 56 |
|
|---|
| 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>] |
|---|
| 61 |
<br/> |
|---|
| 62 |
#end for |
|---|
| 63 |
|
|---|
| 64 |
<p>[<a href="./edit">Add new contact</a>]</p> |
|---|
| 65 |
''', [locals(), globals()]) |
|---|
| 66 |
|
|---|
| 67 |
return template.respond() |
|---|
| 68 |
|
|---|
| 69 |
index.exposed = True |
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
def edit(self, id = 0): |
|---|
| 73 |
|
|---|
| 74 |
|
|---|
| 75 |
id = int(id) |
|---|
| 76 |
|
|---|
| 77 |
if id > 0: |
|---|
| 78 |
|
|---|
| 79 |
contact = Contact.get(id) |
|---|
| 80 |
title = "Edit Contact" |
|---|
| 81 |
else: |
|---|
| 82 |
|
|---|
| 83 |
contact = None |
|---|
| 84 |
title = "New Contact" |
|---|
| 85 |
|
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 |
|
|---|
| 90 |
template = Template(''' |
|---|
| 91 |
<h2>$title</h2> |
|---|
| 92 |
|
|---|
| 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" /> |
|---|
| 101 |
</form> |
|---|
| 102 |
''', [locals(), globals()]) |
|---|
| 103 |
|
|---|
| 104 |
return template.respond() |
|---|
| 105 |
|
|---|
| 106 |
edit.exposed = True |
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 |
def delete(self, id): |
|---|
| 110 |
|
|---|
| 111 |
contact = Contact.get(int(id)) |
|---|
| 112 |
contact.destroySelf() |
|---|
| 113 |
return 'Deleted. <a href="./">Return to Index</a>' |
|---|
| 114 |
|
|---|
| 115 |
delete.exposed = True |
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| 118 |
def store(self, lastName, firstName, phone, email, url, id = None): |
|---|
| 119 |
if id and int(id) > 0: |
|---|
| 120 |
|
|---|
| 121 |
contact = Contact.get(int(id)) |
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 |
|
|---|
| 126 |
contact.set( |
|---|
| 127 |
lastName = lastName, |
|---|
| 128 |
firstName = firstName, |
|---|
| 129 |
phone = phone, |
|---|
| 130 |
email = email, |
|---|
| 131 |
url = url) |
|---|
| 132 |
else: |
|---|
| 133 |
|
|---|
| 134 |
contact = Contact( |
|---|
| 135 |
lastName = lastName, |
|---|
| 136 |
firstName = firstName, |
|---|
| 137 |
phone = phone, |
|---|
| 138 |
email = email, |
|---|
| 139 |
url = url) |
|---|
| 140 |
|
|---|
| 141 |
return 'Stored. <a href="./">Return to Index</a>' |
|---|
| 142 |
|
|---|
| 143 |
store.exposed = True |
|---|
| 144 |
|
|---|
| 145 |
|
|---|
| 146 |
def reset(self): |
|---|
| 147 |
|
|---|
| 148 |
Contact.dropTable(True) |
|---|
| 149 |
|
|---|
| 150 |
|
|---|
| 151 |
Contact.createTable() |
|---|
| 152 |
|
|---|
| 153 |
|
|---|
| 154 |
Contact( |
|---|
| 155 |
firstName = 'Hendrik', |
|---|
| 156 |
lastName = 'Mans', |
|---|
| 157 |
email = 'hendrik@mans.de', |
|---|
| 158 |
phone = '++49 89 12345678', |
|---|
| 159 |
url = 'http://www.mornography.de') |
|---|
| 160 |
|
|---|
| 161 |
return "reset completed!" |
|---|
| 162 |
|
|---|
| 163 |
reset.exposed = True |
|---|
| 164 |
|
|---|
| 165 |
|
|---|
| 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!" |
|---|
| 167 |
|
|---|
| 168 |
cherrypy.quickstart(ContactManager()) |
|---|