Web 框架

一、Web 框架

Web 框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。这大多数的 Web框架提供了一套开发和部署网站的方式,也为 Web行为提供了一套通用的方法。Web 框架已经实现了很多功能,开发人员使用框架提供的方法并且完成自己的业务逻辑,就能快速开发 Web 应用。浏览器和服务器的是基于 HTTP 协议进行通信的。也可以说 Web 框架就是在以上十几行代码基础张扩展出来的,有很多简单方便使用的方法,大大提高了开发的效率

1. wsgiref 模块

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

如果要动态生成 HTML,就需要把上述步骤自己来实现。不过,接受 HTTP 请求、解析 HTTP 请求、发送 HTTP 响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态 HTML 呢,就得花个把月去读 HTTP 规范

正确的做法是底层代码由专门的服务器软件实现,我们用 Python 专注于生成 HTML 文档。因为我们不希望接触到TCP 连接、HTTP 原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python 编写 Web 业务。这个接口就是 WSGI:Web Server Gateway Interface。而 wsgiref 模块就是 Python 基于 wsgi 协议开发的服务模块

import time
from wsgiref.simple_server import make_server

# 将返回不同的内容部分封装成函数
def index(url):
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
        now = str(time.time())
        s = s.replace("@@oo@@", now)
    return bytes(s, encoding="utf8")

def home(url):
    with open("home.html", "r", encoding="utf8") as f:
        s = f.read()
    return bytes(s, encoding="utf8")

# 定义一个 url 和实际要执行的函数的对应关系
list1 = [
    ("/index/", index),
    ("/home/", home),
]

def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 设置 HTTP 响应的状态码和头信息
    url = environ['PATH_INFO']  # 取到用户输入的 url
    func = None
    for i in list1:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found!"
    return [response, ]

if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8080, run_server)
    print("我在 8080 等你哦...")
    httpd.serve_forever()

2. jinja2 模块

上面的代码实现了一个简单的动态,我完全可以从数据库中查询数据,然后去替换我 html 中的对应内容,然后再发送给浏览器完成渲染。 这个过程就相当于 HTML 模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具: jinja2

1) 下载 jinjia2

pip install jinja2

index.html 文件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
</head>
<body>
    <h1>姓名:{{name}}</h1>
    <h1>爱好:</h1>
    <ul>
        {% for hobby in hobby_list %}
        <li>{{hobby}}</li>
        {% endfor %}
    </ul>
</body>
</html>

2) 使用 jinja2 渲染 index.html 文件

from wsgiref.simple_server import make_server
from jinja2 import Template

def index():
    with open("index2.html", "r") as f:
        data = f.read()
    template = Template(data)  # 生成模板文件
    ret = template.render({"name": "Alex", "hobby_list": ["烫头", "泡吧"]})  # 把数据填充到模板里面
    return [bytes(ret, encoding="utf8"), ]

def home():
    with open("home.html", "rb") as f:
        data = f.read()
    return [data, ]

# 定义一个url和函数的对应关系
URL_LIST = [
    ("/index/", index),
    ("/home/", home),
]

def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 设置HTTP响应的状态码和头信息
    url = environ['PATH_INFO']  # 取到用户输入的url
    func = None  # 将要执行的函数
    for i in URL_LIST:
        if i[0] == url:
            func = i[1]  # 去之前定义好的url列表里找url应该执行的函数
            break
    if func:  # 如果能找到要执行的函数
        return func()  # 返回函数的执行结果
    else:
        return [bytes("404没有该页面", encoding="utf8"), ]

if __name__ == '__main__':
    httpd = make_server('', 8000, run_server)
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()

当然除了自己手写数据之外,也可以从数据库中查询数据

使用 pymysql 连接数据库

conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="xxx", db="xxx", charset="utf8")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select name, age, department_id from userinfo")
user_list = cursor.fetchall()
cursor.close()
conn.close()

创建一个测试的 user 表

CREATE TABLE user(
  id int auto_increment PRIMARY KEY,
  name CHAR(10) NOT NULL,
  hobby CHAR(20) NOT NULL
)engine=innodb DEFAULT charset=UTF8;

模板的原理就是字符串替换,我们只要在 HTML 页面中遵循 jinja2 的语法规则写上,其内部就会按照指定的语法进行相应的替换,从而达到动态的返回内容

posted @ 2020-06-04 15:36  杼柚  阅读(129)  评论(0编辑  收藏  举报