本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7579622
建立时间:2006年5月29日




[TurboGears]TurboGears快速入门
软件技术

lhwork 发表于 2007/2/16 18:32:34

在这篇文章当中主要讲解入门教程和关于信息。这篇文章将成为一个很好的入门文档。 这篇文章界于入门文档和手册之间。入门文档覆盖特定知识点,提供快速入门。工作手册提供了具体的工作细节文档。 这份快速入门指南提供了在不需要注意细节情况下的背景知识。 本文档没有包含安装指南,到下载页面会提及相关方法。本指南也没有包含Python的方方面面,可以从很多书籍和资源中得到Python的相关知识。 tg-admin TurboGears的最终应用是以代码文件的形式存在的。正因为如此,代码是描述编程工具的好方法。生成代码最快的方式是使用tg-admin工具。 tg-admin是TurboGears的命令行工具。依靠其子命令可以创建新工程、处理(manipulate)数据库或者以面向对象的特性分析数据库。 tg-admin手册提供了命令细节。如果不提供命令来运行tg-admin,可以得到可用命令列表。 现在,我们使用"quickstart"命令,所以应该使用如下命令: tg-admin quickstart 如果使用"--help"选项,将会得到命令的帮助信息和选项信息。对快速开始,可以使用命令行或者提示符下设置信息。你不需要经常运行quickstart,因为其实它很简单。 这里使用"gs"作为项目名称和包名称,开始我们的项目: Enter project name: gs Enter package name [gs]: creating directory gs generating gs/dev.cfg generating gs/prod.cfg generating gs/gs-start.py generating gs/setup.py creating directory gs/gs generating gs/gs/__init__.py generating gs/gs/controllers.py generating gs/gs/model.py creating directory gs/gs/sqlobject-history creating directory gs/gs/static/css creating directory gs/gs/static/image creating directory gs/gs/static/javascript creating directory gs/gs/templates generating gs/gs/templates/__init__.py generating gs/gs/templates/master.kid generating gs/gs/templates/welcome.kid creating directory gs/gs.egg-info generating gs/gs.egg-info/sqlobject.txt running egg_info writing requirements to ./gs.egg-info/requires.txt writing ./gs.egg-info/PKG-INFO writing top-level name to ./gs.egg-info/top_level.txt 这个命令提供给我们一个WEB应用的模板,可以准备填入实际代码。 Starting up the server 当你运行quickstart时,你已经可以随时准备启动CherryPy的内置服务器了。运行开发服务器使用如下步骤: 1、选择新建工程的顶层目录,本例为"cd gs" 2、运行"python 项目名-start.py",本例为"python gs-start.py" 这时将可以看到服务器启动日志。缺省时使用8080端口,所以可以在"http://localhost:8080"得到欢迎页面。如果在MAC系统下,可以在Bonjour书签看到开发站点。 服务器会自动监视文件更改并自动重启。可以在任何时候按下Control+C来停止服务器。 Configuration 快速开始的例子创建了两个配置文件:dev.cfg和prod.cfg,启动脚本查找setup.py中的当前目录,如果当前在开发模式则使用dev.cfg配置,否则使用prod.cfg配置文件。可以在启动脚本的命令行中指定使用的配置文件。 The Big Picture 这幅图片包含大量的方框和箭头,但是并没有看起来那么复杂。这幅图展示了简历TurboGears应用所需的所有部分。而且大部分是内含在TurboGears当中的。你的应用程序只需要包含亮紫色的盒子。 你的model(模型)对象描述(represent)应用程序使用的书籍。 你的controller(控制)得到用户浏览器的信息,并使用这些信息更新模型中的信息,并准备好用于显示的视图。当然,控制器也选择需要用于返回数据的视图。 在TurboGears里,你的view(视图)就是用于显示controller提供的信息的模板(template)。 你只需要在应用中提供这三个部分即可,其余部分由TurboGears来代劳。 CherryPy可以方便的产生控制器来从网站上获得用户提交的信息。SQLObject可以方便的定义和使用模型。Kid可以产生优秀的HTML页面供给浏览器的显示。MochiKit可以很好的实现浏览器端的复杂行为(behavior),也可以提过Kid生成AJAX格式的请求。 CherryPy Exposed 在CherryPy中,你的网站被描述成一个按照树形组织的对象和他们的方法。按照CherryPy的方式,可以方便的使请求到达目的地。CherryPy指定的请求根路径是cherrypy.root。 如果查看gs-start.py脚本,可以看到如下的代码: from gs.controllers import Root cherrypy.root=Root() 按照习俗(convertion),根控制器类叫做"Root",并且从"controllers.py"模块导入。在很小的应用当中,只要一个控制器模块即可。在大型应用中,(by gashero)你将会希望将应用分为多个包。你还可以使用功能分割(divisions)。如果你希望的话,也可以分别导入不同的包到同一处。 当你确定了控制器包之后,Root就是你的WEB应用(webapp)的根对象。 看看下面的代码来理解URL查找和遍历工作: import turbogears class HardCodedAddition: def cantgohere(self): pass @turbogears.expose() def twoplustwo(self): return "four" @turbogears.expose() def fortyplustwo(self): return "forty-two" class AlwaysSeven: @turbogears.expose() def index(def): return "7" class Root: seven=AlwaysSeven() add=HardCodedAddition() @turbogears.expose() def index(self): return "Welcome" @turbogears.expose() def fun(self): return "... and yet startlingly productive" @turbogears.expose() def default(self,*args): return "The next parts were %s"%str(args) 按照这种设置,我们可以看到TurboGears的URL遍历工作。这些规则用样作用于CherryPy而并非来自TurboGears。 URL路径 返回结果 注释 / Welcome 如果没有指定,则运行index方法 /fun ... and yet startlingly 如果指定了方法,则直接运行此方法 /seven 重定向到/seven/ 子对象按照目录来对待,所以最终被重定向。这是一个很好的特性,可以确保你的相对URL工作正常。 /seven/ 7 运行子对象的index方法 /add/cantgohere 错误 这个对象没有被暴露(exposed)。CherryPy只导航到暴露的方法 /add/twoplustwo four 运行子对象的方法 /foobar The next parts were('foobar') 如果没有找到匹配的URL,则执行default方法 /foobar/baz/bork The next parts were('foobar','baz','bork') 余下部分的URL被分隔发送到default方法的参数。 在构建对象树时,最好还是设置一个default方法,这样可以很好的探测点击的URL。 I wanted an argument! CherryPy的一个很有趣的特性(当然被TurboGears所使用)是从WEB请求得到的参数会自动转换为调用方法的参数。这将会导致处理WEB请求相当的自然。 可以把root设置成如下样式: class Root: @turbogears.expose() def index(self,name="Arthur"): return "I am %s, King of the britons"%name 你将会诧异于访问"/"时返回了"I am Arthur, King of the britons"。缺省的参数在未指定时起效。实际上现在就可以传入参数了,并且按照你期望的方式运行。一个形如"/?name=Lancelot"的请求将会返回"I am Lancelot, King of the britons" 有如Python,调用"/?foobar=baz"将会抛出错误,(by gashero)因为这样将调用root.index(foobar="baz")。所以可以使用如下方式避免: class Root: @turbogears.expose() def index(self,name="Arthur",**kw): return "I am %s, King of the britons"%name 在Python中kw可以接受剩余参数的词典。 Testing, 1... 2... 3... 测试驱动的开发是一种好的开发方式。在编码前先写好测试代码,将会让你明确自己所需要的功能,并提供更好的结构。 如果你不提前写测试,使用自动测试将是更改时的救命者。 当你安装了TurboGears时,可以免费得到TestGears。TestGears是Python的unittest单元测试模块的简单插件,可以免去手动书写测试程序的麻烦。 一份单独(separate)的文档可以覆盖测试的每一个细节。如下是示例控制器代码controllers.py: import turbogears class Root: @turbogears.expose(html="gs.templates.welcome") def index(self,value="0"): value=int(value) return dict(newvalue=value*2) TestGears遍历(look for)模块并启动test_。按惯例(by convertion),测试模块使用单独的包叫做"tests",并放在需要测试的包之下,尽管TestGears并不一定需要这样。如下是简单的测试模块: from turbogears.tests import util from gs.controllers import Root import cherrypy def test withtemplate(): "测试模板输出" cherrypy.root=Root() util.createRequest("/?value=27") assert "The new value is 54." in cherrypy.response.body[0] def test directall(): "测试不使用模板时的方法输出" d=util.call(cherrypy.root.index,"5") assert d["newvalue"]==10 注意,这些只是函数测试,并非unittest.TestCases的测试用例。你仍然可以使用unittest.TestCases的测试用例。测试函数必须以"test"开头。docstring提供了测试程序的正常运行输出。 模板测试使用了受欢迎的模板形式,形如"The new value is ${value}."。运行tests,如下: python setup.py testgears 模板测试按照CherryPy的请求处理机制,所以可以测试各种URL和过滤模板处理。 Validating and converting arguments TurboGears提供了从表单编码到特定Python类型的验证和简单转换方法,如下是示例: import turbogears from turbogears import validators class Root: @turbogears.expose(html="gs.templates.welcome", validators=("value":validators.Int())) def index(self,value=0): return dict(newvalue=value*2) def validation error(self,funcname,kw,errors): #做一些出错时的处理工作 这个传递给turbogaers.expose的字典告知value参数使用Int类型的验证器。这可以确保调用index函数时,value的值是整数类型。 如果验证失败,则validation_error函数被调用,来替换原始目标方法。第一个参数是字符串型,表示验证失败的方法。可以使用一个专用(appropriate)的模板来报警。第二个参数是传递给原方法的参数字典。最后一个参数是抛出的异常列表(list)。 验证失败异常对象提供了用户友好的错误信息。这些对象和原始参数允许你重现(repopulate)一个验证失败的表单入口。 validation_error方法应该做什么呢?他可以做与原方法相同的事情,可以返回字典或字符串,也可以抛出cherrypy.HTTPRedirect来重定向到另外一个页面。这是很好理解的。 所有的验证器(validator)都已经被导入到了turbogears.validators模块中了。可以看到验证器在"FormEncode validators module"和"TurboGears validators module"中是有效的。 可以在FormEncode验证器框架下做很多更加高级的事情。验证器参数可以传递轮廓(schema?)或字典。更多关于轮廓(schema)的信息,参照"FormEncode Validator"文档。 How a view template is chosen 上面已经看过一些使用turbogears.expose中的html参数的引用。这里将会继续讲解。 如果单独使用CherryPy,可以返回一个字符串,并且此字符串被发送到客户端浏览器。但是更多时候,需要返回一个WEB页面。使用TurboGears可以使用Kid模板来返回存在字典中的变量,并传递的html参数到turbogears.expose。 html参数给出了获得Kid模板的完整Python包路径。在项目中,位置应该是"项目名.templates"。模板文件以.kid做扩展名,但只要指定html参数,可以不用在乎这些。所以如果模板叫做"Welcome",则应该使用html="项目名.templates.welcome"。 返回的字典中应该填入需要传递给模板的任何变量。例如返回dict(newvalue=5),则模板中$(newvalue)被替换为5。 有时可能会发现需要一些其他的模板。如果返回的字典包含"tg_template"键,则会自动换用模板系统。返回dict(tg_template="项目名.templates.lancelot")将会使用lancelot模板系统,而不是使用html参数。 Returning XML instead of HTML 最初的Kid是一种基于XML的模板语言。配合HTML串行化器,可以很好的处理HTML。但是使用其他串行化器时,也可以产生XHTML或其他XML格式。 expose(暴露)方法允许指定格式(可以是"json"或Kid的其他串行化器)和内容类型(content_type)。例如,如果你想返回RSS,则可以按照如下配置expose方法: @turbogears.expose(template="project.templates.rss", format="xml",content_type="text/xml+rss") expose方法缺省生成HTML代码,但是更改类型也很容易。注意expose方法要求传递模板到"template"参数代替"html"参数。 Brief introduction to Kid templates Kid模板系统可以是任何的XML文档,但是需要包含Kid可以处理的命名空间(namespace)。下面的例子使用了XHTML文档,转换为有效的HTML文档。 这个例子演示了Kid模板: <?python title="A Kid Test Document" fruits=["apple","orange","kiwi","M&M"] from platform import system?> <html xmlns:py="http://purl.org/kid/ns#"> <head> <title py:content="title">This is replaced.</title> </head> <body> <p>These are some of my favorite fruits:</p> <ul> <li py:for="fruit in fruits"> I like ${fruit}s </li> </ul> <p py:if="system()=='Linux'"> Good for you! </p> </body> </html> Kid模板的注意事项: 不要忘记定义py这个XML命名空间,这是用来让模板识别出有效XML的关键。 ${}用于简单的变量替换,随处可用。 $foo可以替换为foo,但是并不象使用${}那么安全,因为不方便检测变量结束。 这是XHTML,所以必须关闭所有标签,例如HTML中的<br>,到了XHTML中必须写成<br/>。这是转换成HTML所必须的。 因为模板需要使用有效的XML,所以如果你的JavaScript中包含"<" 或">",则需要放在<![CDATA[]]>段中。 Kid模板包含一些特定的保留字,如write、serializer、serialize 、generate、initialize、pull、content、transform。应该避开这些保留字。 Kid一个比较好的特性是,可以在其中所有已知的Python特性。Kid模板将会被编译成Python代码来控制模板的行为。例如:py:for="fruit in fruits"行为表示Python中的"for fruit in fruits:"。 词典中定义的变量是模板的全部可用变量。所有的"py"属性将使用Python的本地变量。如py:for="fruit in fruits"的例子,"fruits"就是一种经由(via)字典传递的序列(iterable)类型。 当模板中的变量被遗弃时,Kid自动避开。你也不需要在意包含"<"的值。例如,你需要确定是否真的需要使用XHTML时。如果是,则将你包装的替换值放入XML()中。例如,我们需要一个叫做"header"的XHTML段。可以表示为${XML(header)},这样"header"将会被丢弃(drop)而自动避开(escape)。 推荐阅读Kid属性语言。 http://kid.lesscode.org/language.html#attribute-language Being Designer-Friendly 如果使用了XHTML,可以使用FireFox浏览器直接打开Kid模板。如果对你很有用,可以这样在浏览器中查看来校准模板外观。 你在找什么?样式表,JavaScript还是变量替换。 有时,使用样式表的href时并非可以达到很好的所见(by gashero)即所得。为了避免(get around)这些,可以使用href来处理浏览器中的模板视图,并且py:attrs来处理生成页面。如: <link rel="stylesheet" type="text/css" href="/Path/To/File.css" py:attrs="href='/path/on/website'"/> 当在浏览器中查看模板时,浏览器只查看href属性,所以样式表可以很好的加载。当模板将要生成最终视图(final viewing)时,Kid将会替换py:attrs中的值,所以样式表可以很好的工作。当处理JavaScript时,这里同样使用src属性来标记脚本。 Application-wide Headers and Footers pp Template variables you get for free pp Using URLs pp JSON outputs pp Brief introduction to MochiKit pp Defining your model 模型是应用操作的数据。TurboGears模型使用SQLObject对象。SQLObject提供了Python对象到关系数据库的桥梁。它并不是设计用来完全隐藏数据库的,未来的设计目标是可以使用Python代码而不是错误的SQL语句。 在TurboGears存取数据库之前,必须指定如何找到数据库。可以在dev.cfg或prod.cfg配置文件中设置。参数"sqlobject.dburi"控制了数据库的存储位置,并使用标准的URI风格。 当然也可以在连接URI中提供"query parameters"选项。一对(couple)有用的选项是debug和debugOutput。如果添加了"?debug=1"到URI,每个查询都会输出运行状态。如果添加了"&debugOutput=1",则可以看到查询结果。 可以在工程目录的model.py中定义数据模型。如果确实很需要将数据保存在多个模块中,也可以将其分布在多个模块中,并确保被model导入。SQLObject提供两种不同的方式定义数据库:可以直接在数据库中定义SQL语句,或在Python中定义。为了代码的简洁,在Python的model中定义更好些。如果希望一个Python类联系到数据库,可以按照如下: from sqlobject import * class Bookt(SQLObject): class sqlmeta: fromDatabase=True 注意这只在某些数据库中有效,具体参考SQLObject文档。 在Python类中定义模型需要输入Python代码,但可以避免书写SQL语句。如下是一个例子BOOK: class Book(SQLObject): isbn=StringCol(length=13,alternateID=True) title=StringCol(length=100) description=StringCol() authors=RelatedJoin("Author") class Authors(SQLObject): last_name=StringCol(length=40) first_name=StringCol(length=40) books=RelatedJoin("Book") 创建数据库使用如下语句: tg-admin sql create 这将会创建三个数据库表格,一个是书籍表,一个作者表,一个多对多的联系表来联系他们。 但是SQLObject不能定义所有的数据库模型,但可以在大多数情况下很好的工作。比如无法很好的定义表名、列名和连接名,来适应已有的数据库。 模型对象无需确保对数据容器的沉默。这些模型对象是完整的Python对象,可以拥有自己的方法和做一些复杂(complex)的计算。 更多相关信息详见SQLObject文档。 Using your model SQLObject可以确保非常方便的访问数据库,有如普通的Python对象一样。SQLObject在后台执行SQL语句来实现这些东东。插入一行记录就是实例化一个对象。下例开启了调试信息(?debug=1&debugOutput=1)。 >>> Book(isbn="1234567890",title="A Fistful of Yen", description="An evocative look at ...") 1/QueryIns: INSERT INTO book (isbn,description,title) VALUES ('1234567890','An evocative look at ...','A Fistful of Yen') 1/QueryIns-> 1 1/COMMIT : auto 1/QueryOne: SELECT isbn, title, description FROM book WHERE id=1 1/QueryR: SELECT isbn, title, description FROM book WHERE id=1 1/QueryOne-> (u'1234567890',u'A Fistful of Yen','An ...') 1/COMMIT : auto <Book 1 isbn='1234567890' title='A Fistful of Yen' description="'An ...'"> 虽然有很多种办法来保留一个主键来保持记录的区别,SQLObject最好使用缺省设置的integer类型的主键。你可以使用SQLObject对象的id属性访问内置的主键。SQLObject可以确保很容易的通过ID属性获取对象。 >>> Book.get(1) 当对某一个特定的列指定了"alternateID",比如上例的"isbn", SQLObject自动创建类方法来方便搜索: >>> Book.byIsbn("1234567890") 当然,更多的时候需要ID之外的查询方式。SQLObject提供了"select"类方法允许制定多种Python形式的查询条件。自定义类的"q"属性提供了存取真实属性的方法。例如,存取isbn列可以用Book.q.isbn。如下例: >>> list(Book.select(AND(LIKE(Book.q.title,"%Fistfull%"), Book.q.isbn="1234567890"))) 在如上例子中,使用list作用于Book.select。select类方法返回一个SelectResults对象。仅在请求数据时SelectResults返回数据,它只是一个结果的占位符。除了可以将结果转换为list之外,还可以使用SelectResults对象的count()方法得到结果记录数量。 数据更新(update)很简单,只要改变属性即可。每次改变属性,SQLObject对象都会执行UPDATE的SQL语句。有时,可能需要一次更改多个列。实例拥有set方法允许一次赋值,如下例: >>> book.title="A Fistful of Foobar" >>> book.set(title="A Fistful of Yen 2:...",isbn="37") TurboGears可以方便的使用事务,通过"连接HUB"。connection hub在需要时自动连接到数据库,并给出方法供开始(begin),提交(commit) ,回滚(rollback)和结束(end)事务。如下例: >>> book.title #"1" >>> hub.begin() >>> book.title="2" >>> hub.rollback() >>> hub.end() >>> book.title #"2" >>> book.sync() >>> book.title #"1" 如上的例子中,先设置了title为1,之后回滚(rollback),并结束了事务,这样等于丢弃了修改。此时对象中的值还是2,但是数据库中的值为1。此时再次同步(sync),就将数据库中的值赋予到了对象中,则title再次变为1。 不像之前的例子,这里没有"COMMIT : auto"。因为使用了事务之后就自动关闭了自动提交,当然还是可以通过增加一个"autoCommit=0"参数到URI之中来开启这个功能。 当对象与数据库不同步时是很不好的。通过调用sync(),可以同步,就是从数据库中重新装入值。 可以通过destroySelf方法删除本记录。 完成...?


阅读全文(12134) | 回复(4) | 编辑 | 精华
 


回复:TurboGears快速入门
软件技术

ymm(游客)发表评论于2009/6/17 16:37:21

前台桌 接待台 展架 货架展架 铁艺展架 展柜 金融街写字楼出租 北京写字楼出租 CBD写字楼出租 北京写字楼 写字楼出租 北京写字楼出售 专利无效 专利诉讼 北京吊车租赁 北京吊车出租 吊车租赁 吊车出租 网络广告机 北京航空快递公司 航空快递公司 国内航空快递 航空快递


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:TurboGears快速入门
软件技术

Jume(游客)发表评论于2009/1/17 20:09:03

很好

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:TurboGears快速入门
软件技术

anyuse(游客)发表评论于2007/5/18 14:26:54

谢谢!

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.078 second(s), page refreshed 144764216 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号