python模拟Django框架实例
一、python实现web服务器 web开发首先要有web服务器才行。比如apache,但是在开发阶段最好有一个简单方便的开发服务器, # -*- coding: utf-8 -*- from wsgiref import simple_server # 定义一个输出 hello world 和环境变量的简单web应用程序 def hello_app(environ,start_response): # 输出 http 头,text/plain 表示是纯文本 start_response('200 OK',[('Content-type','text/plain')]) # 准备输出的内容 content = [] content.append('Hello world') for key,value in environ.items(): content.append('%s : %s' % (key,value)) # 输出,根据 wsgi 协议,返回的需要是一个迭代器,返回一个 list 就可以 return ['n'.join(content)] # 构造开发服务器对象,设置绑定的地址和端口,并把 hello world 应用程序传给他 server = simple_server.make_server('localhost',8080,hello_app) # 启动开发服务器 server.serve_forever() 执行上面这个程序后,打开浏览器,访问一个以 http://localhost:8080 开头的网址即可看到 environ 所包含的内容。 (截取一小部分) 二、基础知识 浏览器和web应用之间使用的是http协议,它规定了请求和响应的格式。 简单使用: >>> # 导入 Request 对象 >>> from webob import Request >>> environ = {} >>> # 使用 Request 来包装 environ 字典 >>> req = Request(environ) 使用一个Request类来包装environ,然后通过Request对象的属性和方法对environ进行访问。由于只有在一个web环境才能得到一个真实的environ字典,为了方便大家在shell中进行测试,webob提供了一个模拟简单web请求的方法: 也可以通过req查找其它有用的信息 同时也可以通过webob模块中的Response对象来包装响应信息。 下面使用webob模块重写之前的hello_app # -*- coding: utf-8 -*- from wsgiref import simple_server from webob import Request,Response # 我们顺便增加了一个功能,就是根据用户在 URL 后面传递的参数 # 显示相应的内容 def hello_app(request): content = [] # 获取 get 请求的参数 content.append('Hello %s'%request.GET['name']) # 输出所有 environ 变量 for key,value in request.environ.items(): content.append('%s : %s' % (key,value)) response = Response(body='n'.join(content)) response.headers['content-type'] = 'text/plain' return response # 对请求和响应进行包装 def wsgi_wrapper(environ,start_response): request = Request(environ) response = hello_app(request) # response 对象本身也实现了与 wsgi 服务器之间通讯的协议, # 所以可以帮我们处理与web服务器之间的交互。 # 这一句比较奇怪,对象使用括号是什么意思。。。。 return response(environ,start_response) server = simple_server.make_server('localhost',wsgi_wrapper) server.serve_forever() 为了让 wsgi_wrapper 更加通用一点,可以把它设计成装饰器的形式: # -*- coding: utf-8 -*- from wsgiref import simple_server from webob import Request,Response # 写成装饰器的 wsgi_wrapper def wsgi_wrapper(func): def new_func(environ,start_response): request = Request(environ) response = func(request) return response(environ,start_response) new_func.__name__ = func.__name__ new_func.__doc__ = func.__doc__ return new_func # 应用程序 @wsgi_wrapper def hello_app(request): content = [] content.append('Hello %s'%request.GET['name']) for key,value)) response = Response(body='n'.join(content)) response.headers['content-type'] = 'text/plain' return response server = simple_server.make_server('localhost',hello_app) server.serve_forever() 三、模板 这里使用Mako,地址http://pypi.python.org/pypi/Mako,下载python setup.py install进行安装 ## -*- coding: utf-8 -*- <html> <head> <title>简单mako模板</title> </head> <body> <h5>Hello ${name}!</h5> <ul> % for key,value in data.items(): <li> ${key} - ${value} <li> % endfor </ul> </body> </html> 保存为simple.html文件,然后需要给模板对象传递data和name两个参数,然后进行渲染,就可以输入html内容 # -*- coding: utf-8 -*- # 导入模板对象 from mako.template import Template # 使用模板文件名构造模板对象 tmpl = Template(filename='./simple.html',output_encoding='utf-8') # 构造一个简单的字典填充模板,并print出来 print tmpl.render(name='python',data = {'a':1,'b':2}) 保存为test_template.py文件,运行就可以输入内容: <html> <head> <title>简单mako模板</title> </head> <body> <h5>Hello python!</h5> <ul> <li> a - 1 <li> <li> b - 2 <li> </ul> </body> </html> 下面对hello_app程序进行重构: # -*- coding: utf-8 -*- from webob import Request def wsgi_wrapper(func): def new_func(environ,start_response) new_func.__name__ = func.__name__ new_func.__doc__ = func.__doc__ return new_func 2. 把 hello_app 给彻底独立出来,形成单独的模块 controller.py : # -*- coding: utf-8 -*- from utils import wsgi_wrapper from webob import Response from mako import Template # 整合了模板功能的 hello_app @wsgi_wrapper def hello_app(request): tmpl = Template(filename='./simple.html',output_encoding='utf-8') content = tmpl.render(name=request.GET['name'],data=request.environ) return Response(body=content) 3. 这样 main.py 就变成这样了: # -*- coding: utf-8 -*- from wsgiref import simple_server from controller import hello_app server = simple_server.make_server('localhost',hello_app) server.serve_forever() 四、ORM(Object Relation Mapping, 对象关系映射) # -*- coding: utf-8 -*- from sqlalchemy import * from sqlalchemy.orm import sessionmaker,scoped_session from sqlalchemy.ext.declarative import declarative_base # 创建数据库引擎,这里我们直接使用 Python2.5 自带的数据库引擎:sqlite, # 直接在当前目录下建立名为 data.db 的数据库 engine = create_engine('sqlite:///data.db') # sqlalchemy 中所有数据库操作都要由某个session来进行管理 # 关于 session 的详细信息请参考:http://www.sqlalchemy.org/docs/05/session.html Session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine)) Base = declarative_base() class Dictionary(Base): # Python 对象对应关系数据库的表名 __tablename__ = 't_dictionary' # 定义自动,参数含义分别为:数据库字段名,字段类型,其他选项 key = Column('key',String(255),primary_key=True) value = Column('value',String(255)) # 创建数据库 Base.metadata.create_all(engine) session = Session() for item in ['python','ruby','java']: # 构造一个对象 dictionary = Dictionary(key=item,value=item.upper()) # 告诉 sqlalchemy ,将该对象加到数据库 session.add(dictionary) # 提交session,在这里才真正执行数据库的操作,添加三条记录到数据库 session.commit() # 查询数据库中Dictionary对象对应的数据 for dictionary in session.query(Dictionary): print dictionary.key,dictionary.value 上面的代码你执行两遍就会报错,为什么。。。因为插入数据库的主键重复了。。。。 # -*- coding: utf-8 -*- from utils import wsgi_wrapper from webob import Response from mako.template import Template # 导入公用的 model 模块 from model import Session,Dictionary @wsgi_wrapper def hello_app(request): session = Session() # 查询到所有 Dictionary 对象 dictionaries = session.query(Dictionary) # 然后根据 Dictionary 对象的 key、value 属性把列表转换成一个字典 data = dict([(dictionary.key,dictionary.value) for dictionary in dictionaries]) tmpl = Template(filename='./simple.html',data=data) return Response(body=content) 五、URL分发控制 # -*- coding: utf-8 -*- from controller import hello_app mappings = [('/hello/{name}',{'GET':hello_app})] 修改main.py # -*- coding: utf-8 -*- from wsgiref import simple_server from urls import mappings from selector import Selector # 构建 url 分发器 app = Selector(mappings) server = simple_server.make_server('localhost',app) server.serve_forever() 然后,在 hello_app 中就可以通过 environ['wsgiorg.routing_args'] 获取到 name 参数了, from webob import Request def wsgi_wrapper(func): def new_func(environ,start_response): request = Request(environ) position_args,keyword_args = environ.get('wsgiorg.routing_args',((),{})) response = func(request,*position_args,**keyword_args) return response(environ,start_response) new_func.__name__ = func.__name__ new_func.__doc__ = func.__doc__ return new_func 那 hello_app 就可以改成这样了: ... @wsgi_wrapper def hello_app(request,name=''): ... content = tmpl.render(name=name,data=data) return Response(body=content) 执行main.py,访问http://localhost:8080/hello/Python 总结 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |