本文主要内容:
从手写框架到用第三方框架的过度,来深入理解第三方框架的好处。
写作的思路是总分总。
先总写:
web框架的推导思路是什么?
用框架的开发效率<—不用框架,自己手写的开发效率
简单的Web框架是:
不用框架,自己手写的开发效率如图所示:
用框架的开发效率如图所示:
再分写:
重要的两个文件:
比如Django框架:
urls.py:专门存放路由与视图函数的对应关系,里面的内容是:
views.py:专门存放视图函数的(也可以是类),里面的内容:
env:这个形参表示的意思是请求相关的所有数据,它是一个字典。以万变应万变,不管有多少个客户端发送的请求,都由env接收,并存入字典。(你只是看到的是变量,其实它是一个大字典,详情往下文看)
三大杀招:
HttpResponse:
作用是返回字符串
render:
作用是返回html页面 并且可以给html页面传数据
还可以说是模板的渲染(将数据在后端按照模板语法放入html对应的位置)
redirect:
作用是重定向
#三大杀招的具体举例
def index(request):
return HttpResponse('你好啊 读者')
def login(request):
return render(request,'login.html',{'user_dict':{'username':'yjg','password':123},'userxxx':'hello world'})
def home(request):
return redirect('https://www.baidu.com')
templates文件夹:
里面存放的是html文件(模板文件)
上面三张图是浏览器(客户端)向服务端发送的三个http请求的数据。
下面三张图是服务端接收到的http请求的数据。
对http请求的数据的一些研究:
为了更好的观察数据的特点:
#请求首行
b'GET / HTTP/1.1\r\n
#请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\n
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
#请求体
#为空
import socket
server = socket.socket()
server.bind(('127.0.0.1',9999))
server.listen(5)
while True:
conn, addr = server.accept()
data = conn.recv(1024)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
print(f"{data}<----")#http的数据
data = data.decode('utf-8') # 一串字符串
target_url = data.split('\r\n')[0].split(' ')[1]
# 判断url返回响应的内容即可
if target_url == '/index':
# conn.send(b'index')
with open(r'D:\py_projects\平时练习\前端\200103.html','rb') as f:
conn.send(f.read())
elif target_url == '/login':
conn.send(b'login')
else:
conn.send(b'404 error')
conn.close()
手写web框架有两点不好:
(1)客户端和服务端会重复写套接字
(2)客户端和服务端会重复写http数据格式
实际情况可能是1000台客户端(甚至更多)与一台服务器交互。那手写岂不要把人逼疯?
变量是变化的,客户端的数量也是变化的,因此用特定的形参env来接受客户端发送的http请求的数据相当于以万变应万变
相关代码如下:
from wsgiref.simple_server import make_server
def run(env,response):
"""
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return: 浏览器能够接受的内容
"""
response('200 OK',[])
print(env) # 大字典里面的PATH_INFO参数就是用户输入的后缀
for k,v in env.items():
print(f"{k}:{v}")
target_url = env.get('PATH_INFO')
if target_url == '/index':
# 一堆逻辑判断
return [b'index']
elif target_url == '/login':
return [b'login']
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run)
# 监听127.0.0.1:8080 一旦有客户端来访问 会立刻将make_server第三个参数加括号调用执行
server.serve_forever() # 启动服务端
查看大字典里重要的参数:服务端的ip地址,端口号和后缀名【因为客户端就是ip地址端口号+后缀名访问服务端的】
再总写:
写web框架的大致思路离不开:
处理http请求并响应http请求(一请求一响应)
手写框架好比重复造轮子,用socket来实现;
用第三方的框架好比轮子造好了,拿来就用,用函数来实现(可能是类中的方法)
再总结Django是如何处理数据请求和响应的【env接收请求,respone接收响应】
from wsgiref.simple_server import make_server
def run(env,response):
"""
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return: 浏览器能够接受的内容
"""
response('200 OK',[])
# print(env) # 大字典里面的PATH_INFO参数就是用户输入的后缀
for k,v in env.items():
print(f"{k}:{v}")
target_url = env.get('PATH_INFO')
if target_url == '/index':
# 一堆逻辑判断
return [b'index']
elif target_url == '/login':
return [b'login']
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run)
# 监听127.0.0.1:8080 一旦有客户端来访问 会立刻将make_server第三个参数加括号调用执行
server.serve_forever() # 启动服务端
根据需求可对服务端的ip地址和端口号以及后缀名作出修改。