欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python模擬Django框架實(shí)例

 更新時(shí)間:2016年05月17日 14:29:36   作者:Senssic  
這篇文章主要為大家詳細(xì)介紹了python模擬Django框架實(shí)例,了解一個(gè)web框架需要的基本功能,感興趣的小伙伴們可以參考一下

一、python實(shí)現(xiàn)web服務(wù)器

web開發(fā)首先要有web服務(wù)器才行。比如apache,但是在開發(fā)階段最好有一個(gè)簡(jiǎn)單方便的開發(fā)服務(wù)器,
容易重啟進(jìn)行調(diào)試,等開發(fā)調(diào)試完畢后,再將代碼部署到成熟穩(wěn)定高效的web服務(wù)器。

# -*- coding: utf-8 -*-
from wsgiref import simple_server

# 定義一個(gè)輸出 hello world 和環(huán)境變量的簡(jiǎn)單web應(yīng)用程序
def hello_app(environ, start_response):
 # 輸出 http 頭,text/plain 表示是純文本
 start_response('200 OK', [('Content-type','text/plain')])
 # 準(zhǔn)備輸出的內(nèi)容
 content = []
 content.append('Hello world')
 for key, value in environ.items():
  content.append('%s : %s' % (key, value))
 # 輸出,根據(jù) wsgi 協(xié)議,返回的需要是一個(gè)迭代器,返回一個(gè) list 就可以
 return ['\n'.join(content)]

# 構(gòu)造開發(fā)服務(wù)器對(duì)象,設(shè)置綁定的地址和端口,并把 hello world 應(yīng)用程序傳給他
server = simple_server.make_server('localhost', 8080, hello_app)
# 啟動(dòng)開發(fā)服務(wù)器
server.serve_forever()

執(zhí)行上面這個(gè)程序后,打開瀏覽器,訪問一個(gè)以 http://localhost:8080 開頭的網(wǎng)址即可看到 environ 所包含的內(nèi)容。

 (截取一小部分)

二、基礎(chǔ)知識(shí)

瀏覽器和web應(yīng)用之間使用的是http協(xié)議,它規(guī)定了請(qǐng)求和響應(yīng)的格式。
1、請(qǐng)求包(Http Request)
請(qǐng)求主要包括請(qǐng)求的方法,請(qǐng)求的URL,請(qǐng)求頭,請(qǐng)求體。
請(qǐng)求的方法http規(guī)定有GET, POST, PUT, DELETE,只不過通過瀏覽器發(fā)起的web請(qǐng)求一般只涉及GET和POST請(qǐng)求。
GET一般用來(lái)獲取服務(wù)器內(nèi)容,POST類似修改內(nèi)容,PUT添加,DELETE刪除。
一般通過提交html的form表單發(fā)起POST請(qǐng)求。成功后需要進(jìn)行重定向。
從協(xié)議上看GET,HTTP請(qǐng)求最大的區(qū)別就是GET請(qǐng)求沒有請(qǐng)求體,而POST請(qǐng)求有。這就意味著可以通過POST請(qǐng)求
向服務(wù)器發(fā)送大量數(shù)據(jù),如上傳文件等,當(dāng)然GET請(qǐng)求也可以通過URL本身以及其參數(shù)向服務(wù)器傳遞參數(shù),比如
url?arg1=value&arg2=value
 請(qǐng)求頭就是包含了請(qǐng)求包的描述信息。 比如編碼,包長(zhǎng)度等。
 2、響應(yīng)包(Http Response)
http的響應(yīng)包的格式更簡(jiǎn)單一些,包括狀態(tài)碼,響應(yīng)頭和響應(yīng)體,狀態(tài)碼表示該請(qǐng)求的結(jié)果,比如
200表示成功
404表示資源沒有找到
500表示服務(wù)器錯(cuò)誤
301表示資源已經(jīng)換了地址,客戶端需要跳轉(zhuǎn)。
響應(yīng)頭和請(qǐng)求頭類似,包括一些描述信息,響應(yīng)體一般就是輸出內(nèi)容了,大部分是頁(yè)面html代碼。
 3、請(qǐng)求的生命周期
1. web服務(wù)器接收到原始的http請(qǐng)求后進(jìn)行一定程度的包裝再交給web應(yīng)用程序
2. web應(yīng)用程序處理后,再以一定的格式返回?cái)?shù)據(jù)給web服務(wù)器
3. web服務(wù)器再將數(shù)據(jù)包裝成http響應(yīng)包返回給瀏覽器。
4、關(guān)于cgi
cgi(common gateway interface)就是web服務(wù)器與web應(yīng)用程序之間的一個(gè)古老的協(xié)議,在cgi協(xié)議中,
web服務(wù)器將http請(qǐng)求的各種信息放到cgi應(yīng)用程序的環(huán)境變量中,cgi應(yīng)用程序再通過標(biāo)準(zhǔn)輸出,輸出它的響應(yīng)頭
和相應(yīng)內(nèi)容給web服務(wù)器。
 上面用到的開發(fā)服務(wù)器與應(yīng)用程序之間所使用的協(xié)議叫做wsgi,它和cgi類似,同樣將請(qǐng)求包裝成一種key-value對(duì),
只不過cgi通過環(huán)境變量傳給cgi應(yīng)用程序,而wsgi直接使用python的字典對(duì)象來(lái)傳遞。 
hello_app的第一個(gè)參數(shù)environ就是包含請(qǐng)求信息的字典對(duì)象,第二個(gè)參數(shù)是個(gè)函數(shù),web應(yīng)用程序在輸出響應(yīng)內(nèi)容
前需要先調(diào)用它來(lái)輸出狀態(tài)碼和響應(yīng)頭。
處理web請(qǐng)求和響應(yīng)這里使用webob模塊來(lái)處理請(qǐng)求和響應(yīng),需要安裝,這里首先要安裝setuptools模塊,一個(gè)包管理的工具,可以通過這個(gè)工具自動(dòng)下載需要的軟件包,類似ubuntu的app-get。下面是地址:http://pypi.python.org/pypi/setuptools安裝結(jié)束,可以直接在命令行中輸入:easy_install webob這樣就會(huì)自動(dòng)下載安裝。

 

 簡(jiǎn)單使用

>>> # 導(dǎo)入 Request 對(duì)象

>>> from webob import Request

>>> environ = {}

>>> # 使用 Request 來(lái)包裝 environ 字典

>>> req = Request(environ)

使用一個(gè)Request類來(lái)包裝environ,然后通過Request對(duì)象的屬性和方法對(duì)environ進(jìn)行訪問。由于只有在一個(gè)web環(huán)境才能得到一個(gè)真實(shí)的environ字典,為了方便大家在shell中進(jìn)行測(cè)試,webob提供了一個(gè)模擬簡(jiǎn)單web請(qǐng)求的方法:

 

也可以通過req查找其它有用的信息

  

同時(shí)也可以通過webob模塊中的Response對(duì)象來(lái)包裝響應(yīng)信息。

下面使用webob模塊重寫之前的hello_app

# -*- coding: utf-8 -*-
from wsgiref import simple_server
from webob import Request, Response


# 我們順便增加了一個(gè)功能,就是根據(jù)用戶在 URL 后面?zhèn)鬟f的參數(shù)
# 顯示相應(yīng)的內(nèi)容
def hello_app(request):
 content = []
 # 獲取 get 請(qǐng)求的參數(shù)
 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

# 對(duì)請(qǐng)求和響應(yīng)進(jìn)行包裝
def wsgi_wrapper(environ, start_response):
 request = Request(environ)
 response = hello_app(request)
 # response 對(duì)象本身也實(shí)現(xiàn)了與 wsgi 服務(wù)器之間通訊的協(xié)議,
 # 所以可以幫我們處理與web服務(wù)器之間的交互。
 # 這一句比較奇怪,對(duì)象使用括號(hào)是什么意思。。。。
 return response(environ, start_response)

server = simple_server.make_server('localhost', 8080, wsgi_wrapper)
server.serve_forever()

為了讓 wsgi_wrapper 更加通用一點(diǎn),可以把它設(shè)計(jì)成裝飾器的形式:

# -*- 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

# 應(yīng)用程序
@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()

三、模板
果然,還是需要用到模板,不能總是直接在Response中寫上長(zhǎng)串的html代碼。
python中的模板引擎主要有mako, genshi, jinjia等。
mako 主要特點(diǎn)在于模板里面 可以比較方便的嵌入Python代碼,而且執(zhí)行效率一流;
genshi 的特點(diǎn)在于基于 xml, 非常簡(jiǎn)單易懂的模板語(yǔ)法,對(duì)于熱愛xhtml的朋友來(lái)說是很好的選擇,
同時(shí)也可以嵌入Python 代碼,實(shí)現(xiàn)一些復(fù)雜的展現(xiàn)邏輯;
jinja genshi 一樣擁有很簡(jiǎn)單的模板語(yǔ)法,只是不 依賴于 xml 的格式,同樣很適合設(shè)計(jì)人員直接進(jìn)行模板的制作,
同時(shí)也可以嵌入Python 代碼實(shí)現(xiàn)一些復(fù)雜的展現(xiàn)邏輯。 

這里使用Mako,地址http://pypi.python.org/pypi/Mako,下載python setup.py install進(jìn)行安裝
簡(jiǎn)單的模塊例子:

## -*- coding: utf-8 -*-
<html>
 <head>
 <title>簡(jiǎn)單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文件,然后需要給模板對(duì)象傳遞data和name兩個(gè)參數(shù),然后進(jìn)行渲染,就可以輸入html內(nèi)容

# -*- coding: utf-8 -*-
# 導(dǎo)入模板對(duì)象
from mako.template import Template
# 使用模板文件名構(gòu)造模板對(duì)象
tmpl = Template(filename='./simple.html', output_encoding='utf-8')
# 構(gòu)造一個(gè)簡(jiǎn)單的字典填充模板,并print出來(lái)
print tmpl.render(name='python', data = {'a':1, 'b':2})

保存為test_template.py文件,運(yùn)行就可以輸入內(nèi)容:
$ python test_template.py

<html>
 <head>
 <title>簡(jiǎn)單mako模板</title>
 </head>
 <body>
 <h5>Hello python!</h5>
 <ul>
  <li>
  a - 1
  <li>
  <li>
  b - 2
  <li>
 </ul>
 </body>
</html>

下面對(duì)hello_app程序進(jìn)行重構(gòu):
1. 把 wsgi_wrapper 單獨(dú)放到通用模塊 utils.py:

# -*- coding: utf-8 -*-
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 給徹底獨(dú)立出來(lái),形成單獨(dú)的模塊 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', 8080, hello_app)
server.serve_forever()

四、ORM(Object Relation Mapping, 對(duì)象關(guān)系映射)
終于也要這一步了,作為web應(yīng)用,還是需要與數(shù)據(jù)庫(kù)進(jìn)行合作。
這里使用sqlalchemy,是一個(gè) ORM (對(duì)象-關(guān)系映射)庫(kù),提供Python對(duì)象與關(guān)系數(shù)據(jù)庫(kù)之間的映射。和Django的models
用法很像,也是可以通過python代碼來(lái)創(chuàng)建數(shù)據(jù)庫(kù)表,并進(jìn)行操作。
sqlalchemy 還可以自動(dòng)映射 Python 對(duì)象的繼承,可以實(shí)現(xiàn)eager loading、lazy loading, 可以直接將 Model 映射到自定
義的 SQL 語(yǔ)句,支持n多的數(shù)據(jù)庫(kù)等等等等。 可以說 sqlalchemy 既有不輸于 Hibernate 的強(qiáng)大功能,同時(shí)不失 Python
的簡(jiǎn)潔優(yōu)雅。
使用方法:

# -*- coding: utf-8 -*-
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base

# 創(chuàng)建數(shù)據(jù)庫(kù)引擎,這里我們直接使用 Python2.5 自帶的數(shù)據(jù)庫(kù)引擎:sqlite,
# 直接在當(dāng)前目錄下建立名為 data.db 的數(shù)據(jù)庫(kù)
engine = create_engine('sqlite:///data.db')
# sqlalchemy 中所有數(shù)據(jù)庫(kù)操作都要由某個(gè)session來(lái)進(jìn)行管理
# 關(guān)于 session 的詳細(xì)信息請(qǐng)參考: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 對(duì)象對(duì)應(yīng)關(guān)系數(shù)據(jù)庫(kù)的表名
 __tablename__ = 't_dictionary'
 # 定義自動(dòng),參數(shù)含義分別為:數(shù)據(jù)庫(kù)字段名,字段類型,其他選項(xiàng)
 key = Column('key', String(255), primary_key=True)
 value = Column('value', String(255))

# 創(chuàng)建數(shù)據(jù)庫(kù)
Base.metadata.create_all(engine)

session = Session()
for item in ['python','ruby','java']:
 # 構(gòu)造一個(gè)對(duì)象
 dictionary = Dictionary(key=item, value=item.upper())
 # 告訴 sqlalchemy ,將該對(duì)象加到數(shù)據(jù)庫(kù)
 session.add(dictionary)

# 提交session,在這里才真正執(zhí)行數(shù)據(jù)庫(kù)的操作,添加三條記錄到數(shù)據(jù)庫(kù)
session.commit()

# 查詢數(shù)據(jù)庫(kù)中Dictionary對(duì)象對(duì)應(yīng)的數(shù)據(jù)
for dictionary in session.query(Dictionary):
 print dictionary.key, dictionary.value

上面的代碼你執(zhí)行兩遍就會(huì)報(bào)錯(cuò),為什么。。。因?yàn)椴迦霐?shù)據(jù)庫(kù)的主鍵重復(fù)了。。。。
 這樣就可以整合到之前的controller.py文件中

# -*- coding: utf-8 -*-
from utils import wsgi_wrapper
from webob import Response
from mako.template import Template
# 導(dǎo)入公用的 model 模塊
from model import Session, Dictionary

@wsgi_wrapper
def hello_app(request):
 session = Session()
 # 查詢到所有 Dictionary 對(duì)象
 dictionaries = session.query(Dictionary)
 # 然后根據(jù) Dictionary 對(duì)象的 key、value 屬性把列表轉(zhuǎn)換成一個(gè)字典
 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分發(fā)控制
給不同的資源設(shè)計(jì)不同的 URL, 客戶端請(qǐng)求這個(gè) URL,web應(yīng)用程序再根據(jù)用戶請(qǐng)求的 URL 定位到具體功能并執(zhí)行之。
提供一個(gè)干凈的 URL 有很多好處:
1. 可讀性,通過 URL 就可以大概了解其提供什么功能
2. 用戶容易記住也方便直接輸入
3.設(shè)計(jì)良好的 URL 一般都更短小精悍,對(duì)搜索引擎也 更友好
使用selector模塊來(lái)處理url映射
下載地址http://pypi.python.org/pypi/selector, 下載那個(gè)source文件進(jìn)行python setup.py install
 首先把urls的配置單獨(dú)放到urls.py中

# -*- 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

# 構(gòu)建 url 分發(fā)器
app = Selector(mappings)
server = simple_server.make_server('localhost', 8080, app)
server.serve_forever()

然后,在 hello_app 中就可以通過 environ['wsgiorg.routing_args'] 獲取到 name 參數(shù)了,
不過在 wsgi_wrapper 其實(shí)還可以進(jìn)一步簡(jiǎn)化 hello_app 的工作: 直接把解析得到的參數(shù)
當(dāng)作函數(shù)參數(shù)傳過去!修改 utils.py:

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)
執(zhí)行main.py,訪問http://localhost:8080/hello/Python

總結(jié)
以上部分的實(shí)現(xiàn),就是類似Django框架中的幾個(gè)主要的功能模塊,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • 使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)做人臉識(shí)別的示例代碼

    使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)做人臉識(shí)別的示例代碼

    這篇文章主要介紹了使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)做人臉識(shí)別的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Python關(guān)于抽獎(jiǎng)系統(tǒng)的思考與設(shè)計(jì)思路

    Python關(guān)于抽獎(jiǎng)系統(tǒng)的思考與設(shè)計(jì)思路

    這篇文章主要介紹了Python關(guān)于抽獎(jiǎng)系統(tǒng)的思考與設(shè)計(jì)思路,本文通過一些簡(jiǎn)單的例子來(lái)說一說抽獎(jiǎng)系統(tǒng)背后的邏輯,看看究竟是你運(yùn)氣不好還是系統(tǒng)邏輯在作怪,需要的朋友可以參考下
    2023-03-03
  • python中日期和時(shí)間格式化輸出的方法小結(jié)

    python中日期和時(shí)間格式化輸出的方法小結(jié)

    這篇文章主要介紹了python中日期和時(shí)間格式化輸出的方法,實(shí)例總結(jié)了Python常見的日期與事件操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-03-03
  • OpenCV特征提取與檢測(cè)之Harris角點(diǎn)檢測(cè)

    OpenCV特征提取與檢測(cè)之Harris角點(diǎn)檢測(cè)

    這篇文章主要給大家介紹了關(guān)于OpenCV特征提取與檢測(cè)之Harris角點(diǎn)檢測(cè)的相關(guān)資料,Harris角點(diǎn)檢測(cè)的目的是去分辨出圖像中的平面、邊界以及角點(diǎn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • 基于python實(shí)現(xiàn)破解滑動(dòng)驗(yàn)證碼過程解析

    基于python實(shí)現(xiàn)破解滑動(dòng)驗(yàn)證碼過程解析

    這篇文章主要介紹了基于python實(shí)現(xiàn)破解滑動(dòng)驗(yàn)證碼過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Linux下編譯安裝MySQL-Python教程

    Linux下編譯安裝MySQL-Python教程

    這篇文章主要介紹了Linux下編譯安裝MySQL-Python教程,本文使用編譯方式安裝,提供下載地址和測(cè)試安裝成功方法,需要的朋友可以參考下
    2015-02-02
  • Django 模板中常用的過濾器實(shí)現(xiàn)

    Django 模板中常用的過濾器實(shí)現(xiàn)

    在模版中,有時(shí)候需要對(duì)一些數(shù)據(jù)進(jìn)行處理以后才能使用。一般在Python中我們是通過函數(shù)的形式來(lái)完成的。而在模版中,則是通過過濾器來(lái)實(shí)現(xiàn)的,本文就來(lái)介紹一下如何實(shí)現(xiàn)
    2021-05-05
  • Python爬取科目四考試題庫(kù)的方法實(shí)現(xiàn)

    Python爬取科目四考試題庫(kù)的方法實(shí)現(xiàn)

    這篇文章主要介紹了Python爬取科目四考試題庫(kù)的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • python遞歸打印某個(gè)目錄的內(nèi)容(實(shí)例講解)

    python遞歸打印某個(gè)目錄的內(nèi)容(實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇python遞歸打印某個(gè)目錄的內(nèi)容(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2017-08-08
  • python自定義類并使用的方法

    python自定義類并使用的方法

    這篇文章主要介紹了python自定義類并使用的方法,涉及Python中類的定義與使用技巧,需要的朋友可以參考下
    2015-05-05

最新評(píng)論