【1.0】web框架
【一】web框架介绍
-
web应用框架,简称为web框架,是建立在web应用的一种方式
-
可以被看作是建立在后端的一个功能强大的socket服务端,用户的浏览器可以看成是拥有可视化界面的socket客户端
-
在架构层面上可以简单的将web框架看作是对前端、数据库的全方位整合
- 就是个管理者,可以连接前端界面和后端数据库,进行一个有序的管理
【二】手打web框架
- 【简介】web框架可以对数据进行收发,结合我们的socket套接字,可以编写出一个简单的web框架
【1】原始版本
(1)服务端(后台)
- 首先只写服务端–出现报错
# 导入socket模块
import socket
IP = '127.0.0.1'
PORT = 8809
# 创建socket对象
server = socket.socket()
# 监听端口
server.bind((IP, PORT))
# 创建半连接池
server.listen(5)
# 服务端接收客户端消息
while True:
sock, addr = server.accept()
data = sock.recv(1024)
print(f'这是来自客户端的数据{data.decode("utf-8")}')
sock.send(b'Hello client')
#断开链接
conn.close()
server.close()
#在后台启动server,并在浏览器中输入ip和端口访问服务器
127.0.0.1:8809
#在浏览器界面会发生错误:返回的信息无效
#在pycharm界面会显示一大串信息,返回出客户端未打开的一大串错误信息
(2)增加http响应模式格式
# 导入socket模块
import socket
IP = '127.0.0.1'
PORT = 8809
# 创建socket对象
server = socket.socket()
# 监听端口
server.bind((IP, PORT))
# 创建半连接池
server.listen(5)
# 服务端接收客户端消息
conn, addr = server.accept()
data = conn.recv(1024)
print(f'这是来自客户端的数据{data.decode("utf-8")}')
#增加响应
back_statue = "HTTP/1.1" + "200 OK" + "\r\n\r\n"
#响应体数据
to_client_data=" this is a message from server"
response_data=back_statue+to_client_data
conn.send(response_data.encode("utf-8"))
#输入正常ip和端口
这是来自客户端的数据GET / HTTP/1.1
#如果在后面还增加一个login 和regiseter
#即我们可以通过这个创建多个名字的浏览器对应一个服务端
这是来自客户端的数据GET login / HTTP/1.1
(4)对浏览器的访问路径进行分配
#解决思路
(1)相应的数据是根据输入的路径进行去别的,我们需要判断路径,不同路径下有不同的信息
(2)重新组装路径和响应数据
(3)得到一个数据
整个过程用函数封装
# 导入socket模块
import socket
IP = '127.0.0.1'
PORT = 8809
server = socket.socket()
server.bind((IP, PORT))
server.listen(5)
# 将响应路径封装成函数
def response(visit_path):
# 增加响应
back_statue = "HTTP/1.1" + "200 OK" + "\r\n\r\n"
# 判断路径
if visit_path == "/":
# 响应体数据
to_client_data = to_client_data = " this is a main message from server"
elif visit_path == "/login":
to_client_data = to_client_data = " this is a login message from server"
elif visit_path == "/register":
to_client_data = " this is a register message from server"
else:
to_client_data = "404"
# 响应体数据
response_data = back_statue + to_client_data
conn.send(response_data.encode("utf-8"))
return response_data
#此处为接收到数据,并且判断路径,在进行发送数据
# 服务端接收客户端消息
conn, addr = server.accept()
data = conn.recv(1024)
#打印出来的就是一大堆的消息,我们的路径在第一行,切片取一下
print(f'这是来自客户端的数据{data.decode("utf-8")}')
visit_path=data.decode().split(" ")[1]
conn.send(response(visit_path))
【三】分层web框架
【0】基础框架
-
#manage.py --创建对象和链接,主要的主体 #response.py --存放响应体和响应的数据 #urls.py --存放映射关系:路径和功能元组列表 #view.py --返回到前端的内容,根据url路径映射到这里面有不同的函数 运行:先从manage建立连接,收到数据,进行响应response(运用到urls找到对应功能,在view进行数据处理)最后回到manage完成一次循环
【1】manage.py
-
# 导入socket模块 import socket from server import urls, response from response import response IP = '127.0.0.1' PORT = 8809 server = socket.socket() server.bind((IP, PORT)) server.listen(5) # 此处为接收到数据,并且判断路径,在进行发送数据 # 服务端接收客户端消息 conn, addr = server.accept() data = conn.recv(1024) # 打印出来的就是一大堆的消息,我们的路径在第一行,切片取一下 print(f'这是来自客户端的数据{data.decode("utf-8")}') # 处理一下客户端的信息 visit_path = data.decode().split(" ")[1] for path_view in urls.urlpatterns: path, view = path_view if path == visit_path: data = view() conn.send(response(data))
-
response.py
#定义响应数据 def response(to_client_data): # 增加响应 back_statue = "HTTP/1.1" + "200 OK" + "\r\n\r\n" # 响应体数据 response_data = back_statue + to_client_data response_data=response_data.encode("utf-8") return response_data
-
urls.py
#对路径处理,建立函数映射 from .view import index,login,register urlpatterns = [ ("/",index), ("/login",login), ("/register",register), ]
-
view.py
#对从客户端浏览器的到的数据进行处理,得到路径 def read_data(path): with open(path,mode='r',encoding='utf-8') as fp: return fp.read() def index(): to_client_data="this is a main message from server" return to_client_data def login(): #登陆界面我们可以进行html渲染 to_client_data=read_data("login.html") return to_client_data def register(): to_client_data = "this is a register message from server" return to_client_data
【四】静态网页和动态网页
- 静态网页
- 该网页的数据是提前写好的,并且不会改变的
- 据此特点,内容固定,不需要服务器额外处理,加载的速度很快
- 动态网页
- 【介绍】网页上只有框架数据,没有真实的数据,想要得到真实的数据就需要配合js动作进行渲染
- 【特点】内容实时更新,需要服务器额外处理,数据交互性比较强
- 【示例】实时的时间展示
【五】基于wsgiref封装响应
-
【介绍】将响应功能进行封装
-
【代码】
from wsgiref import simple_server def run(request,response): response("200 ok",[]) return [b"hello world"] if __name__ == "__main__": ip='127.0.0.1' port=8819 sever=simple_server.make_server(ip,port,run) sever.serve_forever()
【六】基于jianjia2渲染前端
-
服务器处理数据,映射到前端上
from wsgiref import simple_server import time import re # pip install jinjia2 # Template : 模版 from jinja2 import Template def get_time(): c_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) with open("login.html", "r", encoding='utf-8') as fp: data = fp.read() pattern = re.compile("<p >(.*)</p>") pattern.sub(c_time, data) return data def get_dict(): user_dict = {'name': 'dream', 'pwd': 123, 'hobby': 'read'} new_list = [11, 22, 33, 44, 55, 66] with open(r'templates/get_dict.html', 'r', encoding='utf8') as f: data = f.read() # 得到一个实例化后的模版对象 temp_obj = Template(data) # 模版对象的 render 渲染方法 res = temp_obj.render({'user': user_dict, 'new_list': new_list}) return res def run(request, response): # 固定响应格式 response("200 OK", []) return [get_dict().encode()] if __name__ == '__main__': ip = "127.0.0.1" port = 8819 server = simple_server.make_server(ip, port, run) server.serve_forever()
//对应的get_dict.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>字典数据展示</h1> <p>{{ user }}</p> <p>{{ user.name }}</p> <p>{{ user['pwd'] }}</p> <p>{{ user.get('hobby') }}</p> <h1>列表数据展示</h1> <p> {% for i in new_list%} <span>元素:{{ i }}</span> {% endfor %} </p> </body> </html>
【七】请求框架流程分析
-
# Author : Chimengmeng # Time : 2024/6/17 # Blog : https://www.cnblogs.com/dream-ze # Wechat : OXiMengYaO(备注来源) # 【一】浏览器(客户端)发起请求 # 【二】服务端是由 wsgiref 模块启动起来的 # 浏览器的请求会打到 wsgiref 的 request 对象身上 # 比如可以获取到 请求路径 PATH_INFO # 【三】有了请求路径以后调用 urls.py 模块 # 对请求路径进行映射 根据请求路径获取到指定的 函数 地址 # 交给 wsgiref 模块去启动访问 # 【四】到了视图函数 view 内部 # 访问你的数据库读取响应的数据 读取到了小说的标题和内容 # 借助 jianjia2 模块的 模拟语法 # 创建模版对象 将 读取到了小说的标题和内容 渲染到前端页面上 # 模版语法进行渲染 {{ }} / {% %} # 【五】返回给浏览器数据 # 遵循 HTTP 协议 ---> 到了 wsgiref 模块的 response 对象上 # response("200 OK", []) # return 前端页面的二进制数据 # 【六】被浏览器接收到 # 直接对响应体数据进行渲染
【八】常用的web框架
-
# 【一】网络框架 # ● 所谓网络框架是指这样的一组Python包 # 它能够使开发者专注于网站应用业务逻辑的开发,而无须处理网络应用底层的协议、线程、进程等方面。 # 这样能大大提高开发者的工作效率,同时提高网络应用程序的质量。 # ● 在目前Python语言的几十个开发框架中 # 几乎所有的全栈网络框架都强制或引导开发者使用MVC架构开发Web应用。 # ● 所谓全栈网络框架,是指除了封装网络和线程操作,还提供HTTP栈、数据库读写管理、HTML模板引擎等一系列功能的网络框架。 # ● 本文重点讲解的Django、Tornado和Flask是全栈网络框架的典型标杆; # 而 Twisted 更专注于网络底层的高性能封装而不提供HTML模板引擎等界面功能,所以不能称之为全栈框架。 # 【二】MVC 框架 # 【1】model 模型层 # 负责定义数据库的模型表 # 模型层也负责数据库的操作 # 【2】view 视图层 # 用户处理数据及返回数据 # 【3】control 控制层 # 负责将用户前端输入的数据进行采集 # 对视图处理好的数据进行反馈 # 【三】Python中主流的后端框架 # 【1】Django框架 # 历史悠久 很多开发者都在维护 很大 # (2)特点 # [1]完善的文档 # ● 经过10多年的发展和完善,Django有广泛的应用和完善的在线文档,开发者遇到问题时可以搜索在线文档寻求解决方案。 # [2]集成数据访问组件 # ● Django的Model层自带数据库ORM组件,使开发者无须学习其他数据库访问技术(dbi、SQLAlchemy等)。 # [3]强大的URL映射技术 # ● Django使用正则表达式管理URL映射,因此给开发者带来了极高的灵活性。 # [4]后台管理系统自动生成 # ● 开发者只需通过简单的几行配置和代码就可以实现完整的后台数据管理Web控制台。 # [5]错误信息非常完整 # ● 在开发调试过程中如果出现运行异常,则Django可以提供非常完整的错误信息帮助开发者定位问题,比如缺少xxx组件的配置引用等,这样可以使开发者马上改正错误。 # (3)组成结构 # ● Django是遵循MVC架构的Web开发框架,其主要由以下几部分组成。 # ● 管理工具(Management):一套内置的创建站点、迁移数据、维护静态文件的命令工具。 # ● 模型(Model):提供数据访问接口和模块,包括数据字段、元数据、数据关系等的定义及操作。 # ● 视图(View):Django的视图层封装了HTTP Request和Response的一系列操作和数据流,其主要功能包括URL映射机制、绑定模板等。 # ● 模板(Template):是一套Django自己的页面渲染模板语言,用若干内置的tags和filters定义页面的生成方式。 # ● 表单(Form):通过内置的数据类型和控件生成HTML表单。 # ● 管理站(Admin):通过声明需要管理的Model,快速生成后台数据管理网站。 # (4)总结 # ● 大而全 # ○ 自带的功能非常的多 # ○ 但是有时候会略显笨重 # ● 类似于'航空母舰' # 【2】Flask # (1)介绍 # ● Flask是Python Web框架族里比较年轻的一个,于2010年出现,这使得它吸收了其他框架的优点,并且把自己的主要领域定义在了微小项目上。 # ● 同时,它是可扩展的,Flask让开发者自己选择用什么数据库插件存储他们的数据。 # ● 很多功能简单但性能卓越的网站就是基于Flask框架而搭建的,比如httpbin.org就是一个功能简单但性能强大的HTTP测试项目。 # ● Flask是一个面向简单需求和小型应用的微框架。 # (2)特点 # [1]内置开发服务器和调试器 # ● 网络程序调试是在将编制好的网站投入实际运行前,用手工或编译程序等方法进行测试,修正语法错误和逻辑错误的过程。 # ○ 有经验的开发者都知道,这是保证网站系统能够正式应用的必要步骤。 # ● Flask 自带的开发服务器使开发者在调试程序时无须再安装其他任何网络服务器,比如Tomcat、JBoss、Apache等。 # ● Flask默认处于调试状态,使得运行中的任何错误会同时向两个目标发送信息: # ○ 一个是Python Console,即启动Python程序的控制台; # ○ 另一个是HTTP客户端,即Flask开发服务器将调试信息传递给了客户端。 # [2]与Python单元测试功能无缝衔接 # ● 单元测试是对最小软件开发单元的测试,其重点测试程序的内部结构,主要采用白盒测试方法,由开发人员负责。 # ● 单元测试的主要目标是保证函数在给定的输入状态下,能够得到预想的输出,在不符合要求时能够提醒开发人员进行检查。 # ● Flask提供了一个与Python自带的单元测试框架unitest无缝衔接的测试接口,即Flask对象的test_client()函数。 # ● 通过test_client()函数,测试程序可以模拟进行HTTP访问的客户端来调用Flask路由处理函数,并且获取函数的输出来进行自定义的验证。 # [3]使用Jinja2模板 # ● 将HTML页面与后台应用程序联系起来一直是网站程序框架的一个重要目标。 # ● Flask通过使用Jinja2模板技术解决了这个问题。 # ● Jinja2是一个非常灵活的HTML模板技术,它是从Django模板发展而来的,但是比Django模板使用起来更加自由且更加高效。 # ● Jinja2模板使用配制的语义系统,提供灵活的模板继承技术,自动抗击XSS跨站攻击并且易于调试。 # [5]完全兼容WSGI 1.0标准 # ● WSGI(Web Server Gateway Interface)具有很强的伸缩性且能运行于多线程或多进程环境下,因为Python线程全局锁的存在,使得WSGI的这个特性至关重要。 # ● WSGI已经是Python界的一个主要标准,各种大型网路服务器对其都有良好的支持。 # ● WSGI位于Web应用程序与Web服务器之间,与WSGI完全兼容使得Flask能够配置到各种大型网络服务器中。 # [6]基于Unicode编码 # ● Flask是完全基于Unicode的。这对制作非纯ASCII字符集的网站来说非常方便。 # ● HTTP本身是基于字节的,也就是说任何编码格式都可以在HTTP中传输。 # ● 但是,HTTP要求在HTTP Head中显式地声明在本次传输中所应用的编码格式。 # ● 在默认情况下,Flask会自动添加一个UTF-8编码格式的HTTP Head,使程序员无须担心编码的问题。 # (3)总结 # ● 小而精 # ○ 自带的功能非常的少 # ○ 但是第三方模块非常的多 # ● 类似于'游骑兵' # ● flask的第三方模块加到一起甚至比django还多 # ○ 并且也越来越像django # ● flask由于过多的依赖于第三方模块 # ○ 有时候也会受制于第三方模块 # 【3】Tornado # (1)介绍 # ● Tornado是使用Python编写的一个强大的可扩展的Web服务器。 # ● 它在处理高网络流量时表现得足够强健,却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中。 # ● Tornado作为FriendFeed网站的基础框架,于2009年9月10日发布,目前已经获得了很多社区的支持,并且在一系列不同的场合中得到应用。 # ● 除FriendFeed和Facebook外,还有很多公司在生产上转向Tornado,包括Quora、Turntable.fm、Bit.ly、Hipmunk及MyYearbook等。 # (2)特点 # ● 完备的Web框架:与Django、Flask等一样,Tornado也提供了URL路由映射、Request上下文、基于模板的页面渲染技术等开发Web应用的必备工具。 # ● 是一个高效的网络库,性能与Twisted、Gevent等底层Python框架相媲美:提供了异步I/O支持、超时事件处理。这使得Tornado除了可以作为Web应用服务器框架,还可以用来做爬虫应用、物联网关、游戏服务器等后台应用。 # ● 提供高效HTTPClient:除了服务器端框架,Tornado还提供了基于异步框架的HTTP客户端。 # ● 提供高效的内部HTTP服务器:虽然其他Python网络框架(Django、Flask)也提供了内部HTTP服务器, # 但它们的HTTP服务器由于性能原因只能用于测试环境。 # 而Tornado的HTTP服务器与Tornado异步调用紧密结合,可以直接用于生产环境。 # ● 完备的WebSocket支持:WebSocket是HTML5的一种新标准,实现了浏览器与服务器之间的双向实时通信。 # (3)总结 # ● 异步非阻塞框架 # ○ 速度极快 # ○ 常被用作大型站点的接口服务框架 # ○ 甚至可以用于充当游戏服务器 # 【4】Fastapi # (1)介绍 # ● FastAPI 是一个现代 Web 框架,速度相对较快,用于基于标准 Python 类型提示使用 Python 3.7+ 构建 API。 # ● FastAPI还帮助我们自动为我们的Web服务生成文档,以便其他开发人员可以快速了解如何使用它。 # ● FastAPI 具有许多功能,例如它可以显着提高开发速度,还可以减少代码中的人为错误。 # ● 它很容易学习并且完全可以用于生产。 # ● FastAPI 与众所周知的 API 标准(即OpenAPI 和JSON schema)完全兼容。 # (2)特点 # [1]自动文档 # ● FastAPI 使用 OpenAPI 标准自动生成交互式 API 文档。 # ● 可以通过访问应用程序中的特定端点来访问此文档,这使得理解和测试 API 变得非常容易,而无需手动编写大量文档。 # [2]Python 类型提示 # ● FastAPI 的突出功能之一是它使用 Python 类型提示。 # ● 通过使用类型提示注释函数参数和返回类型,不仅可以提高代码可读性,还可以使 FastAPI 自动验证传入数据并生成准确的 API 文档。 # ● 此功能使我们的代码不易出错并且更加自我记录。 # [3]数据验证 # ● FastAPI 使用 Pydantic 模型进行数据验证。 # ● 可以使用 Pydantic 的架构和验证功能定义数据模型。 # ● 这可确保传入数据自动验证、序列化和反序列化,从而降低在应用程序中处理无效数据的风险。 # [4]异步支持 # ● 随着Python异步编程的兴起,FastAPI完全拥抱异步操作。 # ● 可以使用Python的async和await关键字来编写异步端点,使其非常适合处理I/O密集型任务并提高应用程序的整体响应能力。 # [5]依赖注入 # ● FastAPI 支持依赖注入,允许声明端点的依赖关系。 # ● 这有助于保持代码模块化、可测试和可维护。 # ● 我们可以将数据库连接、身份验证等依赖项无缝地注入到的路由中。 # [6]安全功能 # ● FastAPI 包含各种开箱即用的安全功能,例如对 OAuth2、JWT(JSON Web 令牌)的支持以及请求数据的自动验证,以防止 SQL 注入和跨站点脚本 (XSS) 攻击等常见安全漏洞。 # 框架的核心逻辑几乎是一致的 我们在学习的时候只需要先学会一种之后就可以触类旁通 # ● Django 框架官网:https://www.djangoproject.com/ # ● Flask 框架官网:https://flask.palletsprojects.com/en/3.0.x/ # ● Fastapi框架官网:https://fastapi.tiangolo.com/ # ● Pyramind框架官网:https://trypyramid.com/ # ● Tornado框架官网:https://www.tornadoweb.org/en/stable/ # ● Sanic框架官网:https://github.com/sanic-org/sanic # ● Aiohttp框架官网:https://docs.aiohttp.org/en/stable/