status

校对

HuangYi,ZoomQuiet

完成度:15%

TableOfContents

PCS304 Web应用框架纵览

概述
  • 简洁的介绍知识点的来由
    Python Web应用框架纵论 ::
     
        +-- 导论
        |  +-- 现状
        |  \-- 为什么Python 中有这么多框架?
        +-- 分类
        |  +-- 如何来理解各种框架?
        |  +-- 框架的框架
        |  +-- 轻型框架
        |  +-- 一站式框架
        |  \-- 模板系统
        +-- 细说(按照历史顺序,选择经典框架来介绍,没有PCS独立章节的,和故事没有直接提及的)
        |  +-- Zope/Plone (请潘俊勇撰写)
        |  +-- Quixote (请 阿北或是朞其它豆瓣成员 撰写)
        |  +-- Quixote (请 阿北 撰写)
        |  +-- Django (HY自写)
        |  \-- UliWeb (请Limodou撰写)
        +-- 选择
        |  +-- 个人
        |  +-- 团队
        |  \-- 企业
        \-- 小结
          \-- 选择的痛苦

为啥介多框架?!

还有人站着说话不腰痛的分析"[http://xlp223.yculblog.com/post.1634226.html 为何有如此多的python web 框架?]" {{{脚注: 访问地址:http://xlp223.yculblog.com/post.1634226.html 精巧地址:http://tinyurl.com/6yajuo }}}

{{{脚注: 访问地址:http://bitworking.org/news/Why_so_many_Python_web_frameworks 精巧地址:http://tinyurl.com/6kv9j3 }}}

{{{注意: 在上述文章中,作者为了展示任何人可以通过Python快速创建自个儿的Web应用框架, 当场使用 9个文件创建并运行了一个含有足够功能的框架! 详细请参看本章最后的小结部分 }}}

Joe Gregorio的超级框架

组成
  1. model.py

       1 from sqlalchemy import Table, Column, String
       2 import dbconfig
       3 
       4 entry_table = Table('entry', dbconfig.metadata,
       5              Column('id', String(100), primary_key=True),
       6              Column('title', String(100)),
       7              Column('content', String(30000)),
       8              Column('updated', String(20), index=True)
       9          )
    
  2. dbconfig.py

       1 from sqlalchemy import *
       2 
       3 metadata = BoundMetaData('sqlite:///tutorial.db')
    
  3. manage.py

       1 import os, sys
       2 
       3 def create():
       4     from sqlalchemy import Table
       5     import model
       6     for (name, table) in vars(model).iteritems():
       7         if isinstance(table, Table):
       8             table.create()
       9 
      10 def run():
      11     import urls
      12     if os.environ.get("REQUEST_METHOD", ""):
      13         from wsgiref.handlers import BaseCGIHandler
      14         BaseCGIHandler(sys.stdin, sys.stdout, sys.stderr, os.environ).run(urls.urls)
      15     else:
      16         from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
      17         httpd = WSGIServer(('', 8080), WSGIRequestHandler)
      18         httpd.set_app(urls.urls)
      19         print "Serving HTTP on %s port %s ..." % httpd.socket.getsockname()
      20         httpd.serve_forever()
      21 
      22 if __name__ == "__main__":
      23    if 'create' in sys.argv:
      24         create()
      25    if 'run' in sys.argv:
      26         run()
    
  4. view.py

       1 import selector
       2 import view
       3 
       4 urls = selector.Selector()
       5 urls.add('/blog/', GET=view.list)
       6 urls.add('/blog/{id}/', GET=view.member_get)
       7 urls.add('/blog/;create_form', POST=view.create, GET=view.list)
       8 urls.add('/blog/{id}/;edit_form', GET=view.member_get, POST=view.member_update)
    
  5. model.py

       1 import robaccia
       2 import model
       3 
       4 def list(environ, start_response):
       5     rows = model.entry_table.select().execute()
       6     return robaccia.render(start_response, 'list.html', locals())
       7 
       8 def member_get(environ, start_response):
       9     id = environ['selector.vars']['id']
      10     row = model.entry_table.select(model.entry_table.c.id==id).execute().fetchone()
      11     return robaccia.render(start_response, 'entry.html', locals())
      12 
      13 def create(environ, start_response):
      14     pass
      15 def create_form(environ, start_response):
      16     pass
      17 def member_edit_form(environ, start_response):
      18     pass
      19 def member_update(environ, start_response):
      20     pass
    
  6. robaccia.py

       1 import kid
       2 import os
       3 
       4 extensions = {
       5     'html': 'text/html',
       6     'atom': 'application/atom+xml'
       7     }
       8 
       9 def render(start_response, template_file, vars):
      10     ext = template_file.rsplit(".")
      11     contenttype = "text/html"
      12     if len(ext) > 1 and (ext[1] in extensions):
      13         contenttype = extensions[ext[1]]
      14 
      15     template = kid.Template(file=os.path.join('templates', template_file), **vars)
      16     body = template.serialize(encoding='utf-8')
      17 
      18     start_response("200 OK", [('Content-Type', contenttype)])
      19     return [body]
    
  7. list.html

    <?xml version="1.0" encoding="utf-8"?>
    <html xmlns:py="http://purl.org/kid/ns#>">
    <head>
     <title>A Robaccia Blog</title> 
     </head>
    <div py:for="row in rows.fetchall()">
    <h2>${row.title}</h2>
    <div>${row.content}</div>
    <p><a href="./${row.id}/">${row.updated}</a></p>
    </div>
    </html>
使用
  1. 创建数据库

    ~$ python manage.py create
  2. 初始化数据

    ~$ python
    Python 2.4.3 (#2, Apr 27 2006, 14:43:58)
    [GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import model
    >>> i = model.entry_table.insert()
    >>> i.execute(id='first-post', title="Some Title", content="Some pithy text...",  
       updated="2006-09-01T01:00:00Z")
    
    >>> i.execute(id='second-post', title="Moving On", content="Some not so pithy words...",  
       updated="2006-09-01T01:01:00Z")
  3. 独立运行

    ~$ python manage.py run
    Serving HTTP on 0.0.0.0 port 8080 ...
  4. 通过 cgi 在各种Web服务器中运行

    import manage
    manage.run()
能力

使用

问题

探讨

Eurasia3 前面已经

支持 Mako 的 <%def name=""> <%call expr=""> <% python code %> ${...}

from template import compile, Template

s = '''\
<%def name="test2(a, b)">
 ${caller.test3()} or ${context.get('test3', None)()}

 %if a:
  ${a}
 %elif b:
  ${b}
 %else:
  <%write('hello')%>
 %endif

 %for i in xrange(100):
  ${str(i)}
 %endfor
</%def>

<%def name="test(c, d)">
 <%call expr="test2(1, 2)">
  <%def name="test3()">
   <%
    x = 1
   %>
   hello world! in test3
  </%def>
 </%call>
</%def>
'''

print compile(s)

m = Template(s)
print m.test('aaa', 'bbb')

shelve2 已经在实用了。这个模板会被用在建立 Eurasia3 项目主站上

小结


反馈

创建 by -- ::-- ["kongove"] [DateTime(2008-10-30T11:10:42Z)]

PageComment2

[:/PageCommentData:PageCommentData]