Web2py Code Lab

Post on 15-Jan-2015

1.936 views 5 download

description

 

Transcript of Web2py Code Lab

Code Lab

+Colin Su @littleq0903

Python Fundamentals

Installing Python

http://python.org/downloads/

Python 2.7.x

Mac OS X & Linux - no installation needed, it's built-in

Hidden Documentation

help()

dir()

Types

str - String

list - List

tuple - Tuple

dict - Dictionary

String

encode(): Unicode -> Specific Encoding

decode(): Specific Encoding -> Unicode

Python uses Ascii & Unicode

>>> a = 'this is an ASCII string' >>> b = u'This is a Unicode string' >>> a = b.encode('utf8')

List

list is not array, is more like container

mutable container

>>> a = [1, 2, 3] >>> print type(a) <type 'list'> >>> a.append(8) >>> a.insert(2, 7) >>> del a[0] >>> print a [2, 7, 3, 8] >>> print len(a) 4

List - Iteration

List is iterable, you can loop over it

>>> a = [1, 2, 3] >>> for i in a: print i 1 2 3

Tuple

immutable version of List

>>> a = (1, 2, 3) >>> print a[1] 2 >>> a[1] = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment

Dictionary

store a mapping between a set of keys and a set of values

>>> d = {'user':'bozo', 'pswd':1234} !>>> d['user'] 'bozo' !>>> d['pswd'] 1234 !>>> d['bozo'] !Traceback (innermost last): File '<interactive input>' line 1, in ? KeyError: bozo

whlie

>>> i = 0 >>> while i < 10: i = i + 1 >>> print i 10

if ... elif ... else

>>> for i in range(3): >>> if i == 0: >>> print 'zero' >>> elif i == 1: >>> print 'one' >>> else: >>> print 'other' zero one other

try ... except ... else ... finally

>>> try: >>> a = 1 / 0 >>> except Exception, e: >>> print 'oops: %s' % e >>> else: >>> print 'no problem here' >>> finally: >>> print 'done' oops: integer division or modulo by zero done

>>> try: >>> raise SyntaxError >>> except ValueError: >>> print 'value error' >>> except SyntaxError: >>> print 'syntax error' syntax error

exception can be varyall statement for exception handling

Functions

>>> def f(a, b): return a + b >>> print f(4, 2) 6

Functions - default value

>>> def f(a, b=2): return a + b, a - b >>> x, y = f(5) >>> print x 7 >>> print y 3

Function Argument Packaging

arguments could be packaged into list or dictionary

* - position based arguments

** - name based arguments

>>> def f(*a, **b): return a, b >>> x, y = f(3, 'hello', c=4, test='world') >>> print x (3, 'hello') >>> print y {'c':4, 'test':'world'}

Function Argument Unpackaging

Vice versa, arguments could be extracted for functions

>>> def f(a, b): return a + b >>> c = (1, 2) >>> print f(*c) 3

>>> def f(a, b): return a + b >>> c = {'a':1, 'b':2} >>> print f(**c) 3

Lambda

anonymous function

Python features that function as first-class object

>>> a = lambda b: b + 2 >>> print a(3) 5

Class

__init__ as constructor

>>> class MyClass(object): >>> z = 2 >>> def __init__(self, a, b): >>> self.x = a >>> self.y = b >>> def add(self): >>> return self.x + self.y + self.z >>> myinstance = MyClass(3, 4) >>> print myinstance.add() 9

Class - Special Attributes, Methods, Operators

__len__ for len()

__getitem__ for indexing retrieve

__setitem__ for indexing setting

>>> class MyList(object): >>> def __init__(self, *a): self.a = list(a) >>> def __len__(self): return len(self.a) >>> def __getitem__(self, i): return self.a[i] >>> def __setitem__(self, i, j): self.a[i] = j >>> b = MyList(3, 4, 5) >>> print b[1] 4 >>> b.a[1] = 7 >>> print b.a [3, 7, 5]

import

import which, use which

!

import all

!

import renaming

>>> import random >>> print random.randint(0, 9) 5

>>> from random import * >>> print randint(0, 9)

>>> import random as myrand >>> print myrand.randint(0, 9)

Datetime

library for dealing with time-related operation

>>> import datetime >>> print datetime.datetime.today() 2008-07-04 14:03:90 >>> print datetime.date.today() 2008-07-04

Web2py Overview

Download web2py

http://www.web2py.com/init/default/download

Windows & Mac OS X - Packaged Executive

Linux - python web2py.py

Admin Panel

Choose admin password every time

Start server

Keep it open

Your First web2py Website

Application

Administrative interface

Administrative Interface

Installed Application Management

Install & Create New Application

Deployment

Debug

Code Editing

Pre-installed Applications

admin - the one you're using right now

examples - documentation and a replica of official website

welcome - referred as the skeleton of applications

Let's Create a New Application

"New simple application" -> Create

Components In a Application

Models: the data representation

Controllers: application logic and workflow

Views: the data presentation, the interface to users

Languages: i18n, internalization

Modules: Python modules belongs to this application

Static files: image files, CSS files, JavaScript files...

Plugins: extensions of applications

URL Mapping

http://localhost:8000/<application>/<controller>/<handler>

Example

http://localhost:8000/mywebsite/default/index

Application "mywebsite"

Controller "default.py"

Handler "def index(): ..."

Templates

Python Dictionary !{ "first_name": "Colin", "last_name" : "Su" }

HTML Template <!DOCTYPE html> <html> <head> <title>Hello Title</title> </head> <body> <h1>Hello, I'm {{=first_name }} {{=last_name }}</h1> </body> </html>

Rendered HTML <!DOCTYPE html> <html> <head> <title>Hello Title</title> </head> <body> <h1>Hello, I'm Colin Su</h1> </body> </html>

Default Template

controllers/default.py -> index() <=> views/default/index.html

You can change it by response.view = 'default/something.html'

Code Labs

Code Lab 0: Make Your Own Controller

Create codelab_first.py in Controllers

Create codelab_first/index.html in Views

GO EDITING!

Return a Dictionary

Try to return a customized dictionary

Click "exposes: index"codelab_first.py !def index(): my_dict = { "message": "this is message", "massage": "this is massage" } return my_dict

Now Template's Turn

Print your variables out by {{=var}}

codelab_first/index.html !{{extend 'layout.html'}} <h2> {{=message}} </h2> <h3> {{=massage}} </h3>

Debugging a View

{{=BEAUTIFY(response._vars)}} to print out all variables

{{=response.toolbar()}} to enable a debug tool bar

Code Lab 1: Say My Name

codelab_saymyname.py in Controllers

codelab_saymyname/ask.html in Views

codelab_saymyname/say.html in Views

The Cleanest Controller Ever!

Directly return {} since we don't deal with it

codelab_saymyname.py !def ask(): return {} !def say(): return {} !

Create a Form

"action" points to "say"

with a <input> named "visitor_name" codelab_saymyname/ask.html !{{extend 'layout.html'}} <h1> What's Your Name? </h1> <form action="say"> <input name="visitor_name" /> <input type="submit" /> </form> !

Let it go say

Get POST parameters by request.vars.var_name

codelab_saymyname/say.html !{{extend 'layout.html'}} <h1> Hello {{=request.vars.visitor_name}} </h1> !!!

Core Components

web2py Libraries

are exposed to the handlers as global objects

Ex. request, response, BEAUTIFY...

source code files are in gluon folder

web2py/gluon gluon/__init__.py gluon/highlight.py gluon/restricted.py gluon/streamer.py gluon/admin.py gluon/html.py gluon/rewrite.py gluon/template.py gluon/cache.py gluon/http.py gluon/rocket.py gluon/storage.py gluon/cfs.py gluon/import_all.py gluon/sanitizer.py gluon/tools.py gluon/compileapp.py gluon/languages.py gluon/serializers.py gluon/utils.py gluon/contenttype.py gluon/main.py gluon/settings.py gluon/validators.py gluon/dal.py gluon/myregex.py gluon/shell.py gluon/widget.py gluon/decoder.py gluon/newcron.py gluon/sql.py gluon/winservice.py gluon/fileutils.py gluon/portalocker.py gluon/sqlhtml.py gluon/xmlrpc.py gluon/globals.py gluon/reserved_sql_keywords.py !

web2py APIs - Global Objects

request - all configuration in HTTP request

response - all configuration in HTTP response

session

cache

request Object

extends Python dict class

basically a dictionary, but can be accessed as attributesrequest.vars or request['vars']

if an attribute does not exist, it returns None instead of an exception

read-only dictionary

Key Attributes in request Object

Dictionary-likedrequest.cookies request.env request.varsrequest.get_varsrequest.post_vars

Stringrequest.applicationrequest.controller request.function request.extension

Booleanrequest.is_local request.is_httpsrequest.ajax

Datetime request.now request.utcnow

(more...)

response Object

extends the same super class of request

it's a read-write dictionary (request is read-only)

usually affects the browser behavior

Key Attributes in response Object

Dictionary-likedresponse.cookiesresponse.headersresponse.metaresponse._vars

Strings response.titleresponse.jsresponse.delimiters [] response.view response.status

Functions response.flash() response.toolbar() response.write()

!

(more...)

Session

also the Storage class (same of request, response)

the same user + the same time of login session

Operating Sessions

storing into session

!

!

retrieving from session

Python !session.myvariable = "hello"

Python !a = session.myvariable

Operating Sessions

Drops off all sessions

!

!

Made sessions only be transferred under HTTPS protocol

Python !session.forget(response)

Python !session.secure()

Caching

cache has two attributes: cache.ram, cache.disk

format: cache(<name>, <function>)

Caching in Memory

the output of lambda: time.ctime() is cached for 5 secs

'time' is used as the caching key

Python !def cache_in_ram(): import time t = cache.ram('time', lambda: time.ctime(), time_expire=5) return dict(time=t, link=A('click me', _href=request.url))

Responding

HTTP()

redirect()

URL()

HTTP()

It's an exception, need to be raised

determine the http responding status code e.g. 404, 500

HTTP(<status code>, <message>)

Python !def page_not_found(): raise HTTP(404, 'my message')

redirect()

redirect(<URL to redirect>)

Python !def index(): redirect("http://www.google.com")

URL()

generates internal URL path for actions or static files

all arguments will be parsed automatically

Python !URL('f') >>> "/[application]/[controller]/f" !URL('f', args=['x', 'y'], vars=dict(z='t')) >>> "/[application]/[controller]/f/x/y?z=t"

If you want to redirect to any application

Python !redirect(URL('f', args=['x', 'y'], vars=dict(z='t')))

The Views

HTML Helpers

generate any HTML tag in Python format

_ prefixed argument as html attribute

Template !{{=DIV('thisisatest', _id='123', _class='myclass')}} !-> <div id="123" class="myclass">thisisatest</div>

Template Basic Syntax

for ... in

while

if ... elif ... else

try ... except ... else ... finally

def .... return

for ... in

{{pass}} as ending

Template !{{items = ['a', 'b', 'c']}} <ul> {{for item in items:}}<li>{{=item}}</li>{{pass}} </ul>

Rendered !<ul> <li>a</li> <li>b</li> <li>c</li> </ul> !

while

the condition expression needs to be given

Template !{{k = 3}} <ul> {{while k > 0:}}<li>{{=k}}{{k = k - 1}}</li>{{pass}} </ul>

Rendered !<ul> <li>3</li> <li>2</li> <li>1</li> </ul> !

if ... elif ... else

Template !{{ import random k = random.randint(0, 100) }} <h2> {{=k}} {{if k % 4 == 0:}}is divisible by 4 {{elif k % 2 == 0:}}is even {{else:}}is odd {{pass}} </h2>

Rendered !<h2> 64 is divisible by 4 </h2> !!

try ... except ... else ... finally

Template !{{try:}} Hello {{= 1 / 0}} {{except:}} division by zero {{else:}} no division by zero {{finally}} <br /> {{pass}}

Rendered !Hello division by zero <br /> !

def ... return

Template !{{def itemize(link):}} <li><a href="http://{{=link}}">{{=link}}</a></li> {{return}} <ul> {{itemize('www.google.com')}} </ul>

Rendered !<ul> <li><a href="http:/www.google.com">www.google.com</a></li> </ul>

Database

Abstraction Layer

In web2py, database operation has been abstracted into Python objects

No SQL needed, but the conception of SQL is still important

define your models in Models files

Connection

SQLite is file-based database which is widely used in development

scheme: sqlite://<filename>

Python !db = DAL('sqlite://storage.db') !

Creating Tables

db.define_table(table_name, field1, field2 ... )

Python !db.define_table( 'purchase', Field('buyer_id', db.person), Field('product_id', db.product), Field('quantity', 'integer'), format = '%(quantity)s %(product_id)s -> %(buyer_id)s') !

Query

conditions as query, connected with a "|"

Python !my_query = (db.mytable.myfield != None) | (db.mytable.myfield > 'A') rows = db(my_query).select() !for row in rows: print row.myfield !!

Insert

db.<table>.insert

db.<table>.bulk_insert

Python !>>> db.person.insert(name="Alex") 1 >>> db.person.insert(name="Bob") 2 !>>> db.person.bulk_insert([{'name':'Alex'}, {'name':'John'}, {'name':'Tim'}]) [3,4,5]

Transaction

db.commit()

db.rollback()

rollback will ignore all operations since the last commit

Transaction Example

commit one more time to make changes to database

Python !db.commit() try: db.person.insert(name="bob") except: db.rollback() else: db.commit() !

Practice & Resource of Web2py

Practices

From the online web2py book

03 Overview

04 The core

05 The views

06 The database abstraction layer

07 Forms and validators

Resources

Quick Examples (Snippets)http://www.web2py.com/examples/default/examples

Online Book (free) http://web2py.com/books/default/chapter/29/00/preface

Python Cheat-sheet http://rgruet.free.fr/PQR26/PQR2.6_modern_a4.pdf

Open Source Project Contribution

Discussion is important

mailing list

documentation

IRC Channel

STFW & RTFM & GIYF

Git

version control system

coding history

distributed version control

Github

http://www.slideshare.net/littleq0903/introduction-to-git-10706480

Google Summer of Code

Sahana is the accepted organization again and again and again....

Google pays you if you spend your summer for coding

Idea Page

Idea -> Proposal -> get a mentor -> coding

https://developers.google.com/open-source/soc/

Thanks

Good luck to your development