Skip to content

Commit 1b35df9

Browse files
committed
docs for user input and database
1 parent 945c0c3 commit 1b35df9

File tree

3 files changed

+223
-0
lines changed

3 files changed

+223
-0
lines changed

docs/db.rst

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
Accessing the database
2+
======================
3+
4+
Web.py provides a simple and uniform interface to the database that you want to work with, whether it is PostgreSQL, MySQL, SQLite or any other. It doesn't try to build layers between you and your database. Rather, it tries to make it easy to perform common tasks, and get out of your way when you need to do more advanced things.
5+
6+
7+
Create a database object
8+
------------------------
9+
10+
You could create a database object with `web.database()`. Make sure that you have appropriate database library installed.
11+
12+
PostgreSQL
13+
``````````
14+
Database Library: `psycopg2`
15+
::
16+
17+
db = web.database(dbn='postgres', db='dbname', user='username', pw='password')
18+
19+
MySQL
20+
`````
21+
Database Library: `MySQLdb`
22+
::
23+
24+
db = web.database(dbn='mysql', db='dbname', user='username', pw='password')
25+
26+
27+
SQLite
28+
``````
29+
30+
Database Library: `sqlite3`
31+
::
32+
33+
db = web.database(dbn='sqlite', db='dbname')
34+
35+
36+
Multiple databases
37+
``````````````````
38+
39+
Working with more databases is not at all difficult with web.py. Here's what you do.
40+
41+
::
42+
43+
db1 = web.database(dbn='postgres', db='dbname1', user='username1', pw='password2')
44+
db2 = web.database(dbn='postgres', db='dbname2', user='username2', pw='password2')
45+
46+
And use `db1`, `db2` to access those databases respectively.
47+
48+
49+
Operations
50+
----------
51+
`web.database()` returns an object which provide you all the functionality to insert, select, update and delete data from your database. For each of the methods on `db` below, you can pass `_test=True` to see the SQL statement rather than executing it.
52+
53+
54+
Inserting
55+
`````````
56+
::
57+
58+
# Insert an entry into table 'user'
59+
userid = db.insert('user', firstname="Bob", lastname="Smith", joindate=web.SQLLiteral("NOW()"))
60+
61+
62+
The first argument is the table name and the rest of them are set of named arguments which represent the fields in the table. If values are not given, the database may create default values or issue a warning.
63+
64+
For bulk insertion rather than inserting record by record, use `multiple_insert` rather.
65+
66+
Bulk Inserting
67+
``````````````
68+
69+
70+
Selecting
71+
`````````
72+
To select `all` the rows from the `user` table, you would simply do
73+
74+
::
75+
76+
users = db.select('user')
77+
78+
For the real world use cases, `select` method takes `vars`, `what`, `where`, `order`, `group`, `limit`, `offset`, and `_test` optional parameters.
79+
80+
::
81+
82+
users = db.select('users', where="id>100")
83+
84+
To prevent SQL injection attacks, you can use `$key` in where clause and pass the `vars` which has { 'key': value }.
85+
86+
::
87+
88+
vars = dict(name="Bob")
89+
results = db.select('users', where="name = $name", vars=vars, _test=True)
90+
>>> results
91+
<sql: "SELECT * FROM users WHERE name = 'Bob'">
92+
93+
94+
Advanced querying
95+
`````````````````
96+
97+
Many a times, there is more to do with the database, rather than the simple operations which can be done by `insert`, `select`, `delete` and `update` - Things like your favorite (or scary) joins, counts etc. All these are possible with `query` method, which also takes `vars`.
98+
99+
::
100+
101+
results = db.query("SELECT COUNT(*) AS total_users FROM users")
102+
print results[0].total_users # prints number of entries in 'users' table
103+
104+
Joining tables
105+
::
106+
107+
results = db.query("SELECT * FROM entries JOIN users WHERE entries.author_id = users.id")
108+
109+
110+
Updating
111+
````````
112+
The `update` method accepts same kind of arguments as Select. It returns the number of rows updated.
113+
114+
::
115+
116+
num_updated = db.update('users', where="id = 10", firstname = "Foo")
117+
118+
Deleting
119+
````````
120+
The `delete` method returns the number of rows deleted. It also accepts "using" and "vars" parameters. See ``Selecting`` for more details on `vars`.
121+
122+
::
123+
124+
num_deleted = db.delete('users', where="id=10")
125+
126+
127+
128+

docs/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Contents:
1111
.. toctree::
1212
:maxdepth: 2
1313

14+
input
15+
db
16+
1417
Hello World
1518
===========
1619

docs/input.rst

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
Accessing User Input
2+
====================
3+
4+
While building web applications, one basic and important thing is to respond to the user input that is sent to the server.
5+
6+
Web.py makes it easy to access that whether it is parameters in the url (`GET` request) or the form data (`POST` or `PUT` request). The `web.input()` method returns a dictionary-like object (more specifically a `web.storage` object) that contains the user input, whatever the request method is.
7+
8+
9+
To access the URL parameters (?key=value) from the `web.input` object, just use `web.input().key`.
10+
11+
GET
12+
---
13+
14+
For a URL which looks like `/page?id=1&action=edit`, you do
15+
16+
::
17+
18+
class Page(object):
19+
def GET(self):
20+
data = web.input()
21+
id = int(data.id) # all the inputs are now strings. Cast it to int, to get integer.
22+
action = data.action
23+
...
24+
25+
`KeyError` exception is thrown if `key` is not there in the URL parameters.
26+
Web.py makes it easier to handle that with default values to web.input().
27+
28+
::
29+
30+
class Page(object):
31+
def GET(self):
32+
data = web.input(id=1, action='read')
33+
id, action = int(data.id), data.action
34+
...
35+
36+
POST
37+
----
38+
39+
It works exactly the same way with POST method. If you have a form with `name` and `password` elements, you would do
40+
41+
::
42+
43+
class Login(object):
44+
def POST(self):
45+
data = web.input()
46+
name, password = data.name, data.password
47+
...
48+
49+
50+
Multiple inputs with same name
51+
------------------------------
52+
53+
What if you have a URL which looks like `/page?id=1&id=2&id=3` or you have a form with multiple selects? What would `web.input().id` give us? It simply swallows all but one value. But to let web.input() know that we're expecting more values with the same name is simple. Just pass `[]` as the default argument for that name.
54+
55+
::
56+
57+
class Page(object):
58+
def GET(self):
59+
data = web.input(id=[])
60+
ids = data.id # now, `ids` is a list with all the `id`s.
61+
...
62+
63+
64+
File uploads
65+
------------
66+
67+
Uploading files is easy with web.py. `web.input()` takes care of that too. Just make sure that the upload form has an attribute enctype="multipart/form-data". The `input()` gives you `filename` and `value`, which are the uploaded file name and the contents of it, respectively.
68+
To make things simpler, it also gives you `file`, a file-like object if you pass `myfile={}` where `myfile` is the name of the input element in your form.
69+
::
70+
71+
class Upload(object):
72+
def GET(self):
73+
return render.upload()
74+
75+
def POST(self):
76+
data = web.input(myfile={})
77+
fp = data.myfile
78+
save(fp) # fp.filename, fp.read() gives name and contents of the file
79+
...
80+
81+
or
82+
83+
::
84+
85+
class Upload(object):
86+
...
87+
88+
def POST(self):
89+
data = web.input() # notice that `myfile={}` is missing here.
90+
fp = data.myfile
91+
save(fp.filename, fp.value)
92+
...

0 commit comments

Comments
 (0)