Django框架学习——python模拟Django框架(转载)
原贴来源
python实现web服务器
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()
(截取一小部分) 基础知识
处理web请求和响应

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', 8080, wsgi_wrapper)
server.serve_forever()
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 in request.environ.items():
content.append('%s : %s' % (key, value))
response = Response(body='\n'.join(content))
response.headers['content-type'] = 'text/plain'
return response
server = simple_server.make_server('localhost', 8080, hello_app)
server.serve_forever()
模板
- mako 主要特点在于模板里面 可以比较方便的嵌入Python代码,而且执行效率一流;
- genshi 的特点在于基于 xml, 非常简单易懂的模板语法,对于热爱xhtml的朋友来说是很好的选择,
- jinja 和 genshi 一样拥有很简单的模板语法,只是不 依赖于 xml 的格式,同样很适合设计人员直接进行模板的制作,
<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内容
# 导入模板对象
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})
<head>
<title>简单mako模板</title>
</head>
<body>
<h5>Hello python!</h5>
<ul>
<li>
a - 1
<li>
<li>
b - 2
<li>
</ul>
</body>
</html>
from webob import Request
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
2. 把 hello_app 给彻底独立出来,形成单独的模块 controller.py :
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 就变成这样了:
from wsgiref import simple_server
from controller import hello_app
server = simple_server.make_server('localhost', 8080, hello_app)
server.serve_forever()
ORM(Object Relation Mapping, 对象关系映射)
终于也要这一步了,作为web应用,还是需要与数据库进行合作。这里使用sqlalchemy,是一个 ORM (对象-关系映射)库,提供Python对象与关系数据库之间的映射。和Django的models用法很像,也是可以通过python代码来创建数据库表,并进行操作。 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
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', output_encoding='utf-8')
content = tmpl.render(name=request.GET['name'], data=data)
return Response(body=content)
URL分发控制
from controller import hello_app
mappings = [('/hello/{name}', {'GET':hello_app})]
修改main.py
from wsgiref import simple_server
from urls import mappings
from selector import Selector
# 构建 url 分发器
app = Selector(mappings)
server = simple_server.make_server('localhost', 8080, app)
server.serve_forever()
然后,在 hello_app 中就可以通过 environ['wsgiorg.routing_args'] 获取到 name 参数了,
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
总结
Django框架学习——python模拟Django框架(转载)的更多相关文章
- Django视频教程 - 基于Python的Web框架(全13集)
Django是由Python驱动的开源模型-视图-控制器(MVC)风格的Web应用程序框架,使用Django可以在即可分钟内快速开发一个高品质易维护数据库驱动的应用程序.下面是一大坨关于Django应 ...
- 在学习python的Django\Flask\Tornado前你需要知道的,what is web?
我们都在讲web开发web开发,那到底什么是web呢? 如果你正在学习python三大主流web框架,那这些你必须要知道了 软件开发架构: C/S架构:Client/Server 客户端与服务端 ...
- 网站开发学习Python实现-Django的models学习-生鲜项目(6.3.2)
@ 目录 1.说明 2.模型类的设计 3.代码的具体实现 4.详情地址 关于作者 1.说明 models是django的很重要的部分,所以深入研究. 本文章的所研究项目为黑马教育python课程中的项 ...
- Django中国|Django中文社区——python、django爱好者交流社区
Django中国致力于成为Python和Django框架等技术的中文开发者学习交流平台. 内容涵盖python教程.python基础.Django教程.python入门.web.py教程.linux教 ...
- 网站开发学习Python实现-Django项目部署-介绍(6.2.1)
@ 目录 1.第一步:找源码 2.第二步:在windows中更改代码 2.第三步:同步到linux中 3.第三步:部署 4.第四步:运行 关于作者 1.第一步:找源码 从github上找一个djang ...
- 网站开发学习Python实现-Django学习-总结(6.1.2)
@ 目录 1.MVT 2.模型 3.视图 4.模板 5.常用的命令 6.pycharm创建django工程 关于作者 1.MVT 项目结构如下,其中项目同名文件夹为配置文件 每一个项目有多个应用(未考 ...
- 网站开发学习Python实现-Django学习-介绍(6.1.1)
@ 目录 1.MVT 2.ORM 关于作者 1.MVT 主要的目的是为了快速,简便的开发数据库驱动的网站,强调代码的复用,多个组件可以很方便以插件的方式服务于整个框架,采用的是MVT设计模式(差不多的 ...
- 网站开发学习Python实现-Django项目部署-同步之前写的博客(6.2.2)
@ 目录 1.说明 2.思路 3.代码 关于作者 1.说明 之前写的博客都在csdn和博客园中 要将博客同步到自己的博客网站中 因为都是使用markdown格式书写的,所以直接爬取上传就完事 2.思路 ...
- 网站开发学习Python实现-Django学习-自学注意(6.1.3)
@ 目录 1.配置文件相关 2.应用创建相关 3.项目相关 4.模板相关 5.其他 关于作者 1.配置文件相关 1.可以更改时间,地区相关(国际化) 2.BASE_DIR很重要,一个工程要有很好的移植 ...
随机推荐
- Python Base One
//this is my first day to study python, in order to review, every day i will make notes (2016/7/31) ...
- java面试题之HashMap和TreeMap的区别
HashMap和TreeMap的区别 相同点: 都是以key和value的形式存储: key不可以重复: 都是线程不安全的: 不同点: HashMap的key可以为空 TreeMap的key值是有序的 ...
- poj 2379 Sum of Consecutive Prime Numbers
...
- 【CF20C】Dijkstra?(DIJKSTRA+HEAP)
没什么可以说的 做dijk+heap模板吧 以后考试时候看情况选择SFPA和DIJKSTRA ; ..]of longint; dis:..]of int64; a:..]of int64; b:.. ...
- 获取本机外网IP的工具类
ExternalIpAddressFetcher.java package com.tyust.common; import java.io.IOException; import java.io.I ...
- 关于toggle的用法
//一个关于鼠标点击 切换场景的代码段 $(document).on('click', '.create-advice-elseparm', function () { $('.advice-else ...
- LeetCode OJ——Minimum Depth of Binary Tree
http://oj.leetcode.com/problems/minimum-depth-of-binary-tree/ 贡献了一次runtime error,因为如果输入为{}即空的时候,出现了c ...
- 快速上手 Echarts
最近使用到了 百度的 Echarts 数据可视化工具,这里简单介绍如何快速上手. 一.下载 这里选择目前最新版本,4.2.1 地址:https://github.com/apache/incubato ...
- 洛谷——P2658 汽车拉力比赛
P2658 汽车拉力比赛 题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间. 其中一些 ...
- GRDB使用SQLite的WAL模式
GRDB使用SQLite的WAL模式 WAL全称是Write Ahead Logging,它是SQLite中实现原子事务的一种机制.该模式是从SQLite 3.7.0版本引入的.再此之前,SQLi ...