您现在的位置: 捷凌网安 >> 编程语言 >> Linux编程 >> Python编程 >> 正文
使用TurboGears和Python开发Web 站点

作者:佚名 责任编辑:左决 点击数: 更新时间:2008-2-21 6:56:21

   如果浏览器没有自动打开这个地址,请手工输入 Toolbox 服务器所指定的 URL(http://localhost:7654/),并点击 CatWalk 链接打开 CatWalk。


图 1. CatWalk 工具
CatWalk 工具

    Toolbox 是面向开发人员的,而不是面向终端用户的,它最适合辅助完成数据模型化和为应用程序快速提供数据。我们可以使用 Ctrl-C 关闭 toolbox 服务器。在本文介绍中,我们将不会使用这个工具。

创建视图

     在 TurboGears 中创建视图的默认方法是使用 Kid XML 模板化语言。由于 Kid 使用了 XML,因此所有的模板都必须很好地进行格式化,否则在呈现时就会抛出异常。Kid 还可以支持模板继承(template inherITance),这样所生成的新模板就可以对基本模板进行扩充,从而可以在一个地方创建并维护通用代码。

    在 TurboGears 中,Kid 文件都位于 templates 目录中,扩展名为 .kid。默认情况下,有一个 master.kid 文件和一个 welcome.kid 文件,其中 master.kid 文件是基础模板文件,welcome.kid 在其 <html> 标记中使用 py:extends 属性对其进行了继承。

    要创建一个新模板,我建议您对 welcome.kid 文件进行拷贝或重命名,并使用它作为起点开始下一步的工作。对于本例来说,我们首先创建的是分类模板,它会显示有关给定分类的以下信息:

  • 分类名(tITle 和 breadcrumb)
  • 到祖先的链接(breadcrumb)
  • 到子分类的链接(list)
  • 到产品的链接(list)


清单 11. 分类页面 kid 模板文件(category.kid)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:py="http://purl.org/kid/ns#"
    py:extends="'master.kid'">
<head>
    <title>Category: ${category.name}</tITle>
</head>
<body>
 <div id="breadcrumbs">
  <ul>
  <li py:for="ancestor in list(category.ancestors)[::-1]">
    >
    <a href="/category/${ancestor.id}"
     py:content="ancestor.name"></a>
   </li>
   <li id="active">
    > <span py:replace="category.name" />
   </li>
  </ul>
 </div>
 <div id="subcategories" py:if="category.subcategories">
  <div class="header">Subcategories</div>
  <ul>
   <li py:for="subcategory in category.subcategories">
    <a href="/category/${subcategory.id}"
     py:content="subcategory.name"></a>
   </li>
  </ul>
 </div>
 <div id="subcategories" py:if="category.products">
  <div class="header">Products</div>
  <ul>
   <li py:for="product in category.products">
    <a href="/product/${product.id}"
     py:content="product.name"></a>
   </li>
  </ul>
 </div>
</body>
</html>
      

清单 11 展示了一些关键的 Kid 功能:

  • 使用 py:extends 继承 master.kid
  • 在 tITle 中使用 ${category.name} 进行表达式替换
  • 使用 py:for 遍历祖先、子分类和产品
  • 使用限制逻辑对在 breadcrumb 中显示的祖先进行反向
  • 使用 py:content 填充链接文本
  • 使用 py:replace 完全替换 span 标记

上面引用的 ancestors 属性要想有效,Category 模型类需要修改成包含一个 _get_ancestors 方法:

清单 12. 将 “ancestors” 属性的 “get” 方法添加到 Category 类中

class Category(SQLObject):
    name = StringCol(length=64)
    parent = ForeignKey('Category', default=None)
    subcategories = MultipleJoin('Category', joinColumn='parent_id')
    products = MultipleJoin('Product')
    def _get_ancestors(self):
 ancestor = self.parent
 while ancestor:
     yield ancestor
     ancestor = ancestor.parent
      


创建控制器

    TurboGears quickstart 提供了一个具有 controllers.py 模块的项目,该模块是 Root 控制器类所在的位置。这是应用程序的主入口点,也是添加新控制器方法的地方。

    下面是 TurboGears expose 中与分类 HTML 模板有关的两个样例控制器方法。控制器方法会返回字典,它们在对指定的 Kid 模板进行呈现时被用作名称空间或上下文。


清单 13. 控制器类

from turbogears import controllers, expose
class Root(controllers.Root):
    @expose("tgcommerce.templates.category")
    def index(self):
 from model import Category
 category = Category.selectBy(parent=None)[0]
 return dict(category=category)
    @expose("tgcommerce.templates.category")
    def category(self, categoryID):
 from model import Category
 category = Category.get(categoryID)
 return dict(category=category)
      

    在 TurboGears 中,URL 非常清楚地映射到方法上,它们都包含在 Root 控制器中。根 URL / 映射为一个名为 index 的特殊方法。通过向 Root 添加一个名为 category 的方法,它就可以通过 URL /category 进行访问了。任何提交的 URL 如果无法匹配给定方法,就会产生一个 404 错误,除非定义了一个 default 方法。

下面是一些可能的 URL 情况及其结果:

  • /:显示没有父 id 的第一个分类
  • /category?categoryID=2:显示 id 值为 2 的分类。
  • /category/1:显示 id 值为 1 的分类(格式为 TG 0.9)
  • /category:抛出一个 500 错误,这是因为缺少分类 id。
  • /xyz:抛出一个 404 错误

图 2 给出了分类显示的页面:


图 2. 分类显示
分类显示 

产品显示

     对于产品显示页面来说,我们要创建一个 product 控制器,它会从数据库中检索出一个产品,并将其传递给 product Kid 模板进行呈现。


清单 14. 增加产品控制器方法

@expose("tgcommerce.templates.product")
def product(self, productID):
    from model import Product
    product = Product.get(productID)
    return dict(product=product)
      

product.kid 模板有一个产品信息表。此处要注意用来显示价格(有两位小数)的 Python 字符串的格式:

清单 15. 分类页 kid 模板文件(product.kid)

<table id="product-info">
  <tr>
    <td class="fld">Name:</td>
    <td class="val"><span py:replace="product.name" /></td>
  </tr>
  <tr>
    <td class="fld">SKU:</td>
    <td class="val"><span py:replace="product.sku" /></td>
  </tr>
  <tr>
    <td class="fld">Price:</td>
    <td class="val">$<span py:replace="'%.2f' % product.price" /></td>
  </tr>
</table>
      


图 3 给出了产品显示页面:


图 3. 产品显示页面
产品显示页面 

错误处理

     控制器方法尚未考虑的一件事是 SQLObject 的 get 方法所抛出的 SQLObjectNotFound 异常。清单 16 给出了捕获这个异常并将其作为 NotFound 异常重新抛出的方法,这会发送一个基本的 HTTP 404 错误:


清单 16. 向 Controller 类添加的错误处理

from model import Category, Product
from sqlobject import SQLObjectNotFound
from cherrypy import NotFound
from turbogears import controllers, expose, url
class Root(controllers.Root):
    @expose("tgcommerce.templates.category")
    def category(self, categoryID):
 try:
     category = Category.get(categoryID)
 except SQLObjectNotFound:
     raise NotFound()
 return dict(category=category)
    @expose("tgcommerce.templates.product")
    def product(self, productID):
 try:
     product = Product.get(productID)
 except SQLObjectNotFound:
     raise NotFound()
 return dict(product=product)
      

     处理找不到对象的错误的另外一个策略不是发送 404 错误,而是对其进行重定向。这是使用 turbogears.redirect(...) 方法实现的:


清单 17. 重定向的例子

from turbogears import redirect
try:
    object = ClassName.get(objectID)
except SQLObjectNotFound:
    raise redirect("/path_to_redirect")
      

上一页  [1] [2] [3] 下一页

  • 上一篇文章:

  • 下一篇文章:
  •  
    最进更新
    普通文章VC++设计超强仿QQ自动伸缩窗04-17
    推荐文章基于HOOK和MMF的Win密码渗透04-17
    推荐文章几种VC++数据库开发技术的相04-17
    普通文章多线程、Socket技术及委托技04-11
    推荐文章VB.Net连接各种数据库的几种04-11
    普通文章VB.NET中的多窗体编程:升级04-11
    普通文章用VB.NET定制Windows控件04-11
    普通文章VB.NET中监视文件夹的变化04-11
    普通文章VB.NET中对象的克隆04-11
    推荐文章VB.NET中的TextBox控件详解04-11
     
    推荐文章
    推荐文章基于HOOK和MMF的Win密码渗透04-17
    推荐文章几种VC++数据库开发技术的相04-17
    推荐文章VB.Net连接各种数据库的几种04-11
    推荐文章VB.NET中的TextBox控件详解04-11
    推荐文章在VB.NET中进行抓屏04-11
    推荐文章VB.Net开发的长内容自动分页04-11
    推荐文章VB.NET中快速访问注册表技巧04-11
    推荐文章PHP5手动最简安装方法03-07
    推荐文章完全讲解PHP+MySQL的分页显示03-07
    推荐文章Linux Shell元字符知识笔记02-21
     
    热点文章 
    普通文章VC++设计超强仿QQ自动伸缩窗04-17
    推荐文章基于HOOK和MMF的Win密码渗透04-17
    推荐文章几种VC++数据库开发技术的相04-17
    普通文章VB.NET中的多窗体编程:升级04-11
    普通文章用VB.NET定制Windows控件04-11
    普通文章VB.NET中对象的克隆04-11
    推荐文章VB.NET中的TextBox控件详解04-11
    普通文章VB/VB.NET/C#导出到Excel的方04-11
    普通文章如何通过VB.NET获取网卡地址04-11
    普通文章VB.NET中使用ListView控件的04-11

    | 设为首页 | 加入收藏 | 联系站长 | 广告服务 | 友情链接 | 版权申明 | 网站地图 |

    在线交流 捷凌网安主群:51649627
    Copyright 2007-2008 © 捷凌网安. All rights reserved.
    备案序号:蜀ICP备08001812号