什么是web框架
框架(framework),指為解決一個(gè)開放性問題而設(shè)計(jì)的具有一定約束的支撐結(jié)構(gòu).
對(duì)于web應(yīng)用來說,其本質(zhì)上就是一個(gè)socket服務(wù)端,下面代碼使用socket實(shí)現(xiàn)一個(gè)靜態(tài)web應(yīng)用:
import socket
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf-8"))
client.send("<h1 style = 'color:red'>Hello, fbo</h1>".encode("utf-8"))
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8001))
sock.listen(5)
while True:
connection, address = sock.accpet()
handle_request(connection)
connection.close()
if __name__ == "__main__":
main()
最簡單的Web應(yīng)用就是把HTML文件先保存好,用一個(gè)現(xiàn)成的http服務(wù)器軟件,從文件中讀取HTML然后返回.
WSGI實(shí)現(xiàn)動(dòng)態(tài)web框架
下面我們來使用Python的WSGI接口來編寫動(dòng)態(tài)web框架
- 簡單的wsgi示例
from wsgiref.simple_server import make_server
def application(environ, start_response):
start_response("200 OK", [('Content-Type', 'text/html')])
return [b'<h1>Hello web!</h1>']
prot = 8080
httpd = make_server('', port, application)
print('Serving Http on port %s...' % (port))
# 開始監(jiān)聽HTTP請求
httpd.serve_forever()
appliction()函數(shù)沒有設(shè)計(jì)到任何解析HTTP的部分,由程序自己封裝;
application()函數(shù)必須由wsgi服務(wù)器來調(diào)用;
python內(nèi)置了一個(gè)WSGI服務(wù)器,這個(gè)模塊叫做wsgiref;
application()函數(shù)就是一個(gè)標(biāo)準(zhǔn)的HTTP處理函數(shù),它接受兩個(gè)函數(shù)environ(包含所有HTTP請求的dict對(duì)象),start_response(一個(gè)發(fā)送HTTP響應(yīng)的函數(shù));
- 定義http路由
print(environ['PATH_INFO'])
path=environ['PATH_INFO']
start_response('200 ok',['Content-Type', 'text/html'])
f1 = open("index.html", "rb")
data1=f1.read()
f1.close()
f2 = open("index2.html", "rb")
data2 = f2.read()
f2.close()
if path == "/index1":
return [data1]
elif path == "/index2":
return [data2]
else:
return ["<h1>404</h1>".encode('utf-8')]
- 將函數(shù)分離
from wsgiref.simple_server import make_server
def f1():
f1.open("index1.html", "rb")
data1=f1.read()
f1.close()
return [data1]
def f2():
f2.open("index2.html", "rb")
data2=f2.read()
f2.close()
return data2
def application(environ, start_response):
print(environ['PATH_INFO'])
path=environ['PATH_INFO']
start_response('200 OK', [('Content-Type', 'text/html')])
if path == '/index1':
return f1()
elif path == '/index2':
return f2()
else:
return ["<h1>404</h1>.encode("utf-8")]
httpd = make_server('', 8502, application)
print("Serving HTTP on 8502...")
httpd.serve_forever()
- 引入模板
from wsgiref import make_server
def f1(req):
print(req)
print(req["QUERY_STRING"])
with open("index1.html", "rb") as f1:
data1 = f1.read()
return [data1]
def f2(req):
with open("index2.html", "rb") as f2:
data2 = f2.read()
return [data2]
import time
def f3(req): # modle and database
with open("index3.html", "rb")
data3 = f3.read()
times = time.strftime("%Y-%m-%d %X", time.localtime())
data3 = str(data3, "utf-8").replace("!time!", str(times))
return [data3.encode("utf-8")]
def routers():
urlpatterns = (
('/index1', f1),
('/index2', f2),
('/cur_time', f3),
)
return urlpatterns
def application(environ, start_response):
print(environ['PATH_INFO'])
path=environ['PATH_INFO']
start_response('200 OK', [('Content-Type', 'text/html')])
urlpatterns = routers()
func = None
for item in urlpatterns:
if item[0] == path:
func = item[1]
break
if func:
return func(environ)
else:
return ["<h1>404</h1>".encode("utf-8")]
httpd = make_server('', 8518, application)
print('Serving HTTP on port 8518...')
httpd.make_serve_forever()
MVC和MTV模式
MVC模式
- M(model): 模型,負(fù)責(zé)與數(shù)據(jù)庫交互
- V(view): 視圖, 展現(xiàn)給用戶的html
- C(Controller), 控制器, url和路由分發(fā)
MTV模式
Django使用的是MTV模式
- Model(模型): 負(fù)責(zé)業(yè)務(wù)對(duì)象與數(shù)據(jù)庫對(duì)象(ORM)
- Template(模板): 負(fù)責(zé)如何把頁面展示給用戶
- View(視圖): 負(fù)責(zé)業(yè)務(wù)邏輯,并在適當(dāng)?shù)臅r(shí)候調(diào)用Model和Template
此外Django還有一個(gè)url分發(fā)器, 將不同的URL請求分發(fā)給不同的view處理
初識(shí)Django(Django使用流程)
# 1. 創(chuàng)建django項(xiàng)目
$ django-admin startproject mysite
$ tree mysite/
mysite/
├── manage.py --> Django項(xiàng)目里面的工具,通過它可以調(diào)用django shell和數(shù)據(jù)庫
└── mysite
├── __init__.py
├── settings.py --> 包含項(xiàng)目默認(rèn)設(shè)置,包括數(shù)據(jù)庫信息,調(diào)試標(biāo)志以及一些工作的變量
├── urls.py --> 負(fù)責(zé)把URL映射到應(yīng)用程序
└── wsgi.py
2. 創(chuàng)建blog應(yīng)用
$ python3 manage.py startapp blog
$ tree
.
├── blog
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py --> 數(shù)據(jù)庫操作
│ ├── tests.py
│ └── views.py --> 寫函數(shù)
├── manage.py
└── mysite
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-35.pyc
│ └── settings.cpython-35.pyc
├── settings.py
├── urls.py
└── wsgi.py
# 3. 啟動(dòng)項(xiàng)目
$ python3 manage.py runserver 8080
Performing system checks...
System check identified no issues (0 silenced).
You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 23, 2018 - 07:11:03
Django version 2.0.1, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CONTROL-C.