Web框架

一.Web框架
1.框架(framework):特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,简单地说,就是用别人搭建好的舞台来表演;使用框架可以帮你快速开发特定的系统

2.对所有Web应用来说,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端

import socket

def handle_request(client):
    buf=client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
    client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))

def main():
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.bind(('localhost',8001))
    sock.listen(5)
    while True:
        connection,address=sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':
    main()

3.为何需要Web框架:将常用功能(HTTP请求,解析HTTP请求,发送HTTP响应)封装,简化工作,无需每次都自己去实现底层代码

最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回

如果要动态生成HTML,就需要自己实现上述步骤;不过,接受HTTP请求,解析HTTP请求,发送HTTP响应都是苦力活;如果自己来写这些底层代码,过于复杂

正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档;因为我们不希望接触TCP连接/HTTP原始请求/响应格式,所以需要1个统一接口,让我们专心用Python编写Web业务

这个接口就是WSGI(Web Server Gateway Interface,Web服务器网关接口),该协议指定了Web服务器和Python Web应用/Web框架之间的标准接口,以提高Web应用在一系列Web服务器间的移植性

  • WSGI是一套接口标准协议/规范
  • 通信(作用)区间是Web服务器和Python Web应用程序之间
  • 目的是制定标准,以保证不同Web服务器可以和不同的Python程序之间相互通信

二.1个最简单的Web框架

from wsgiref.simple_server import make_server
#wsgiref是python内置的服务器模块,进行HTTP解析
import time

def f1(req):#视图函数
    print(req)
    print(req["QUERY_STRING"])
    f1=open("index1.html","rb")
    data1=f1.read()
    return [data1]

def f2(req):
    f2=open("轮播图.html", "rb")
    data2=f2.read()
    return [data2]

def f3(req):#模版以及数据库
    f3=open("index3.html","rb")
    data3=f3.read()
    times=time.strftime("%Y-%m-%d %X",time.localtime())
    data3=str(data3,"utf8").replace("!time!",str(times))
    return [data3.encode("utf8")]

def login(req):
	print(req[QUERY_STRING])#结果为提交的用户名/密码的键值对
	return b"welcome"

def show_time(req):
	times=time.ctime()
	#return ("<h1>%s</h1>"%str(times)).encode("utf-8")
	f=open("show_time.html","rb")
	data=f.read()
	data=data.decode("utf-8")
	data=data.replace("{{time}}",str(times))#将文件数据中的{{time}}替换为times
	#相当于自定义了一种语法,{{..}}部分均被替换
	return data.encode("utf-8")

def routers():
    urlpatterns=(
        ('/yuan',f1),
        ('/alex',f2),
        ("/cur_time",f3),
        ("/login",login),
        ("show_time",show_time)
    )
    return urlpatterns

def application(environ,start_response):
#environ就是服务器打包好的请求对象,是1个dict
    print(environ['PATH_INFO'])
	#PATH_INFO是URL中不存在的部分(IP与端口之后的部分;非请求体)
	#如URL为127.0.0.1:8080/G/programm,PATH_INFO为/G/programm
    path=environ['PATH_INFO']
    start_response('200 OK',[('Content-Type','text/html')])
    #200 OK为状态码;list为请求头,每个键值对构成1个tuple
    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("utf8")]

httpd = make_server('',8080,application)
#参数依次为IP地址,端口,处理请求的函数
print('Serving HTTP on port 8084...')
# 开始监听HTTP请求:
httpd.serve_forever()
#卡住,直到有客户端进行连接,执行application()
  • login.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<form action="http://127.0.0.1:8080/login" method="get">
	<!--GET方式可以访问不同源(协议+域名(IP+端口))数据;(访问)该文件使用的是另1个端口,非8080,不同源-->
	<!--提交到服务端,服务端environ参数为login(),服务端调用login(),浏览器获得返回值并显示-->
	<p>用户名<input type="text" name="user"></p>
	<p>密码<input type="password" name="pwd"></p>
	<p><input type="submit">提交</p>
	</form>
</body>
</html>
  • show_time.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<h1>时间:{{time}}</h1>
	<!--相当于自定义了一种语法,{{..}}部分均被替换-->
</body>
</html>
  • 注意:
整个application()没有涉及任何解析HTTP的部分
也就是说,底层代码不需要自己编写,我们只负责在更高层次上考虑如何响应请求

application()必须由WSGI服务器来调用
有很多符合WSGI规范的服务器,可以挑选一个来用

Python内置了一个WSGI服务器,这个模块叫wsgiref

application()就是符合WSGI标准的一个HTTP处理函数,接收两个参数:
    environ:1个包含所有HTTP请求信息的dict对象
    start_response:1个发送HTTP响应的函数

在application()函数中,调用:
start_response('200 OK', [('Content-Type', 'text/html')])
就发送了HTTP响应的Header
注意Header只能发送一次,也就是只能调用1次start_response()
start_response()函数接收两个参数:
    1个是HTTP状态码
    1个是1list表示的HTTP Header,每个Header用1个包含2strtuple表示

通常情况下,都应该把Content-Type头发送给浏览器
其他很多常用的HTTP Header也应该发送

然后,函数的返回值b'<h1>Hello, web!</h1>'将作为HTTP响应的Body发送给浏览器

有了WSGI,我们关心的就是如何从environ拿到HTTP请求信息
然后构造HTML,通过start_response()发送Header,最后返回Body

三.MVC和MTV模式
1.MVC模式

  • 把Web应用分为模型(Model),控制器(Controller),视图(View)三层
  • 他们之间以一种插件似的,松耦合的方式连接在一起
  • Model负责业务对象与数据库的对象(ORM);View负责与用户的交互(页面;HTML文件);Controller接受用户的输入调用模型和视图,完成用户的请求(视图函数)

在这里插入图片描述
2.MTV模式(Django的模式)

  • 本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同;把Web应用分为模型(Model),模版(Template),视图(View)三层
  • Model负责业务对象与数据库的对象(ORM);Template负责如何把页面展示给用户(HTML文件);View负责业务逻辑,并在适当的时候调用Model和Template(视图函数)
  • Django还有一个URL分发器,作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值