Loading

手动搭建web框架

Web框架本质

  • web框架本质上就是一个socket服务端,但是它的功能非常强大
  • 用户的浏览器可以看作一个拥有可视化界面的socket客户端
  • 两者通过网络请求完成数据交互

手撸Web框架

【1】原始版本

  • web框架可以是自己写的一个简陋的socket服务端
import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
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') # 这里要符合http响应体
    res = data.decode('utf-8').split(' ')[1]
    if res == '/index':
        conn.send(b'index oao')
    elif res == '/login':
        conn.send(b'login oao')
    else:
        conn.send(b'hello web')
    conn.close()
  • 缺陷
1.socket代码过于重复
2.针对http请求数据没有完善的处理方式,自己处理起来很麻烦

【2】基于wsgiref模块搭建web框架

模块封装功能

from wsgiref import simple_server


def run(request, response):
    """
    :param request: 请求相关的数据
    :param response: 响应相关的数据
    :return: 返回给客户端的展示数据
    """
    response('200 OK', [])  # 固定编写 无需掌握
    

    return [b'hello jason']


if __name__ == '__main__':
    server = simple_server.make_server('127.0.0.1', 8080, run)
    '''监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
    server.serve_forever()
# 模块封装了socket代码并将请求数据处理成诸多k:v键值对

路由对应响应

# run函数体中添加下列代码
current_path = request.get("PATH_INFO")
if current_path == '/login':
   return [b'hello login html']
elif current_path == '/register':
   return [b'hello register html']
return [b'404 error']

路由拆分流程

# 当有很多路由和响应的情况下不可能无限制编写if判断语句,应该设置对应关系并动态调用

def register(request):
    return 'register'


def login(request):
    return 'login'

def error(request):
    with open(r'templates/error.html', 'r', encoding='utf8') as f:
        return f.read()

urls = (
    ('/login',login),
    ('/register',register)
)

def run(request, response):
    func_name = None
    for url_tuple in urls:  
        if current_path == url_tuple[0]:
            # 先获取对应的函数名
            func_name = url_tuple[1]
            # 一旦匹配上了 后续的对应关系就无需在循环比对了
            break
    # for循环运行完毕之后 func_name也有可能是None
    if func_name:
        res = func_name(request)
    else:
        res = error(request)  # 顺手将request也传给函数 便于后续数据的获取
    return [res.encode('utf8')]

【3】根据功能的不同拆分成不同的文件

  • views.py
    • 存储路由和函数的对应关系
# 功能函数
def register(request):
    return 'register'


def login(request):
    return 'login'


def index(request):
    return 'index'


def error(request):
    with open(r'templates/error.html', 'r', encoding='utf8') as f:
        return f.read()
  • urls.py
    • 存储函数,路由列表
# 后缀匹配
urls = (
    ('/register', register),
    ('/login', login),
    ('/index', index),
)
  • server.py
    • 存储启动代码,以及函数功能分配代码
from wsgiref import simple_server
from urls import urls
from views import error


def run(request, response):
    response('200 OK', []) 
    current_path = request.get("PATH_INFO")
    func_name = None
    for url_tuple in urls:  # ('/register', register)
        if current_path == url_tuple[0]:
            func_name = url_tuple[1]
            break
    if func_name:
        res = func_name(request)
    else:
        res = error(request) 
    return [res.encode('utf8')]


if __name__ == '__main__':
    server = simple_server.make_server('127.0.0.1', 8080, run)
    server.serve_forever()

总结

  • 拆分后好处在于要想新增一个功能,只需要在views.py中编写函数,urls.py添加对应关系即可

JinJa2模板语法

【1】模块安装

  • JinJa2是第三方模块,需要pip install JinJa2
  • 它支持将数据传输到html页面,并且提供类似于后端语言的语法,可以简单快速的处理数据

【2】动态展示当前时间

  • views.py
from jinja2 import Template
def get_time(env):
    with open('templates/show_time.html', 'r', encoding='utf8') as fp:
        data = fp.read()
    now_time = time.strftime('%Y-%m-%d %H:%M:%S')
    tmp = Template(data)
    res = tmp.render(now_time=now_time)
    return res
  • urls.py
from views import *

urls = [
    ('/time',get_time)
]
  • show_time.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{now_time}}</h1>
</body>
</html>

主要关键字

urls.py
    后缀与函数名对应关系
  ('/index',register)
      后缀专业名词称之为'路由'
        函数名专业名词称之为'视图函数'
        urls.py专业名词称之为'路由层'

views.py
    专门编写业务逻辑代码
      可以是函数 也可以是类
        函数专业名词称之为'视图函数'
        类专业名词称之为'视图类'
        views.py专业名词称之为'视图层'

templates文件夹
    专门存储html文件
      html文件专业名词称之为'模板文件'
        templates文件夹专业名词称之为'模板层'
 
static文件夹
    专门存储静态文件资源
      页面所需css文件、js文件、图片文件、第三方文件可统称为'静态资源'
posted @ 2024-03-24 17:09  HuangQiaoqi  阅读(14)  评论(0编辑  收藏  举报