Web框架

一 web框架

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

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协议开发的服务模块。

from wsgiref.simple_server import make_server

def mya(environ, start_response):
    print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    if environ.get('PATH_INFO') == '/index':
        with open('index.html','rb') as f:
            data=f.read()

    elif environ.get('PATH_INFO') == '/login':
        with open('login.html', 'rb') as f:
            data = f.read()
    else:
        data=b'<h1>Hello, web!</h1>'
    return [data]

if __name__ == '__main__':
    myserver = make_server('', 8011, mya)
    print('监听8010')
    myserver.serve_forever()

二、手撸一个Web框架

启动文件

from wsgiref.simple_server import make_server   #wsgiref把socket进行了一个封装,我们就不需要在进行socket了
import urls
from views import *

# my_server()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:
# environ:一个包含所有HTTP请求信息的dict对象(是一个字典的形式)
# start_response:一个发送HTTP响应的函数。
def my_server(environ, start_response):
    print(environ)
    print(environ['PATH_INFO'])
    # 调用start_response()函数就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。
    # start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP,Header,每个Header用一个包含两个str的tuple表示。
    # 通常情况下,都应该把Content - Type头发送给浏览器。其他很多常用的HTTPHeader也应该发送。
    start_response('200 OK', [('Content-Type', 'text/html')])
    func=None
    for url in urls.urls:
        if url[0]==environ['PATH_INFO']:       #拿到url中ip和端口中的请求地址
            func=url[1]                        #拿到我们分装好的html函数的内存地址,加括号就可以调用,然后取读HTML中的内容,返回给浏览器
            break
    if func:
        response=func(environ)
    else:
        response= error(environ)

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


if __name__ == '__main__':

    my=make_server('127.0.0.1',8001,my_server)           #创建一个服务器,IP地址为127.0.0.1,端口是8000,处理函数是my_server:
    my.serve_forever()                                   #开始监听HTTP请求
wsgireWeb.py

路由配置

import views

urls=[
    ('/index',views.index),
    ('/time',views.time),
    ('/user_list',views.user_list),
    ('/favicon.ico',views.favicon),
]
urls.py

视图函数

import pymysql
from jinja2 import Template
# 1、index和time就是我们封装好的两个从文件夹中读取HTML文件的函数
def index(response):
    with open('templates/index.html','r',encoding='utf-8')  as f:
        data=f.read()

    return data.encode('utf-8')

def time(response):
    import datetime
    now=datetime.datetime.now().strftime('%Y-%m-%d %X')
    with open('templates/two.html','r',encoding='utf-8') as f:
        data=f.read()
    data=data.replace('@@time@@',now)
    return data.encode('utf-8')

# 2、url_list是我们从数据库中读取数据的一个函数
def user_list(response):
    # 连接数据库拿数据
    # 拿到一个数据库连接
    conn=pymysql.connect(host='127.0.0.1',port=3306,user='root',database='test',password='egon123')
    # 拿到一个游标对象
    cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
    # 执行sql
    cursor.execute('select * from user')
    # 把数据拿出来
    user_list=cursor.fetchall()
    print(user_list)
    with open('templates/user_list.html','r',encoding='utf-8')as f:
        data=f.read()
    # 生成一个模板对象,需要传字符串
    template=Template(data)
    # 相当于在执行data.replace(),返回替换完成的字符串
    data=template.render(user_list=user_list)
    return data.encode('utf-8')

# 3、当我们在浏览器中输入的ip和端口后面的不是urls列表中显示的请求地址,就是显示404
def error(request):
    return '404'.encode('utf-8')

# 4、favicon封装的是一个图标的文件,响应到浏览器显示在网页的是一个页面图标
def favicon(request):
    with open('favicon.ico','rb') as f:
        data=f.read()
    return data
views.py

HTML模板templates

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<img src="https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=775f519ac08065386fe7ac41f6b4ca21/fd039245d688d43f63d84526771ed21b0ff43bf5.jpg">'

</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
@@time@@
</body>
</html>
two.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户列表</title>
</head>
<body>
    <table border="1">
        <thead>
        <tr>
            <th>id</th>
            <th>用户名</th>
            <th>密码</th>
        </tr>
        </thead>
        <tbody>
            {% for user in user_list%}
            <tr>
                <td>{{user.id}}</td>
                <td>{{user.name}}</td>
                <td>{{user.password}}</td>
            </tr>

            {%endfor%}
        </tbody>

    </table>


</body>
</html>
user_list.html
原文地址:https://www.cnblogs.com/sui776265233/p/9545689.html