zoukankan      html  css  js  c++  java
  • 第二百五十六节,Web框架

    Web框架

    Web框架本质

    众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

    举例:

    #!/usr/bin/env python
    #coding:utf-8
    import socket #导入单线程通讯模块
    
    def handle_request(client): #发送内容函数
        buf = client.recv(1024)  #设置最大传输字节
        client.sendall(bytes("HTTP/1.1 200 OK
    
    ", encoding='utf-8'))  #向客户端发送内容,以字节形式发送
        client.sendall(bytes("Hello, World欢迎访问", encoding='utf-8'))         #向客户端发送内容
    
    def main(): #创建通讯函数
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    #创建服务端通讯对象
        sock.bind(('localhost',8082))                               #在服务端设置服务端ip和端口
        sock.listen(5)                                              #监听IP和端口,设置一个参数,表示最多连接排队数量
    
        while True: #循环
            connection, address = sock.accept() #等待接收客户端的请求,一旦有客户端请求连接,就会返回两个值,一个是连接对象,一个是客户端的地址信息,所以需要两个变量来接收
            handle_request(connection)          #执行handle_request函数,将客户端请求连接传入handle_request函数
            connection.close()                  #关闭连接
    
    if __name__ == '__main__':                  #wds系统下if __name__ == "__main__"才能创建进程,我们调试没关系,以后在Linux系统没这个问题
        main()                                  #执行main函数

    上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

     

    所以,对于Web框架来说分为两类,一类是即包含了socket服务端,有包含了逻辑处理,一类是只包含逻辑处理需要另外做socket服务端

    python标准库提供的独立WSGI服务器称为wsgiref。

    WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。

    wsgiref模块,python标准库提供的独立WSGI服务器称为wsgiref,就是Web框架逻辑处理包含了socket服务端

    注意:wsgiref模块在python3以上版本有问题,在2.7上可以使用,所以下面的列子在2.7上运行的

    #!/usr/bin/env python
    #coding:utf-8
    from wsgiref.simple_server import make_server  #引入wsgiref的make_server
    
    
    def RunServer(environ, start_response):  #创建通讯内容函数
        start_response('200 OK', [('Content-Type', 'text/html')]) #HTML方式返回内容
        return '<h1>Hello, web!</h1>' #返回内容
    
    
    if __name__ == '__main__':
        httpd = make_server('', 8082, RunServer)    #设置访问端口,和通讯内容函数
        httpd.serve_forever()   #执行通讯函数

    RunServer(environ, start_response)创建通讯内容函数,里面有两个参数
    environ里面包含用户的请求信息如ip等
    start_response里面包含返回信息

    查看方式:

    自定义Web框架

    一、框架

    通过python标准库提供的wsgiref模块开发一个自己的Web框架

    根据用户访问的路径,给出相应的内容

    #!/usr/bin/env python
    #coding:utf-8
    from wsgiref.simple_server import make_server
    
    def index():            #函数返回字符串index
        return 'index'
    
    def login():            #login
        return 'login'
    
    URLS = {                #设置一个字典,键为路径名称,值为函数名称
        "/index":index,
        "/login":login,
    }
    
    def RunServer(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        url = environ['PATH_INFO']  #接收用户访问的路径名称
        if url in URLS.keys():      #判断用户访问路径在URLS字典里是否存在
            furl = URLS[url]        #如果存在通过下标拿到字典里的函数名称
            ret = furl()            #执行函数赋值给ret变量,相当于ret等于函数返回字符串
        else:
            ret = "404"             #如果不存在ret变量等于404
        return ret                  #最后将ret变量返回给浏览器
    
    if __name__ == '__main__':
        httpd = make_server('', 8082, RunServer)
        httpd.serve_forever()

     

    二、模板引擎,和MVC

    MVC框架,就是归类后根据文件夹定义的名字

    在上一步骤中,对于所有的login、index均返回给用户浏览器一个简单的字符串,在现实的Web请求中一般会返回一个复杂的符合HTML规则的字符串,所以我们一般将要返回给用户的HTML写在指定文件中,然后再返回。如:

    模板引擎归类,归类就是为了以后方便管理

    urls.py将映射文件信息写在这个文件里,以后要添加映射就在这里写

    #!/usr/bin/env python
    #coding:utf-8
    import controller
    # 映射文件
    URLS = {                #设置一个字典,键为路径名称,值为函数名称
        "/index":controller.index,
        "/login":controller.login,
    }

    controller.py逻辑处理文件,根据用户访问路径,给出对应的处理,以后要添加逻辑处理函数就写在这里

    #!/usr/bin/env python
    #coding:utf-8
    import os                                                 #引入os模块
    
    # 映射文件对应的函数
    def index():                                              #函数返HTML文件内容
        f = open(os.path.join('views','index.html'),'r')      #拼接路径,打开index.html
        data = f.read()                                       #读出html文件内容
        f.close()                                             #关闭打开的文件
        return data
    
    def login():
        f = open(os.path.join('views', 'login.html'),'r')
        data = f.read()
        f.close()
        return data

    start.py模板引擎启动文件,用于启动模板引擎,一般不做修改

    #!/usr/bin/env python
    #coding:utf-8
    from wsgiref.simple_server import make_server   #导入wsgiref模块里的make_server方法
    from urls import  URLS                          #导入映射文件变量
    
    def RunServer(environ, start_response):         #定义RunServer函数,接收请求信息,和发送内容
        start_response('200 OK', [('Content-Type', 'text/html')])
        url = environ['PATH_INFO']                  #接收用户访问的路径名称
        if url in URLS.keys():                      #判断用户访问路径在URLS字典里是否存在
            furl = URLS[url]                        #如果存在通过下标拿到字典里的函数名称
            ret = furl()                            #执行函数赋值给ret变量,相当于ret等于函数返回字符串
        else:
            ret = "404"                             #如果不存在ret变量等于404
        return ret                                  #最后将ret变量返回给浏览器
    
    if __name__ == '__main__':
        httpd = make_server('', 8082, RunServer)
        httpd.serve_forever()

    views文件夹用于专门存放html文件

    models文件夹用于专门存放数据库处理文件

    整理后的结构

    Web框架,一般根据存放数据库处理文件夹的首字母M,存放html文件夹首字母V,逻辑处理文件首字母C,来命名的,这就是mvc框架

    Web框架运行图

    Web框架请求动态内容

    对于上述代码,虽然可以返回给用户HTML的内容以现实复杂的页面,但是还是存在问题:如何给用户返回动态内容?

    1自定义一套特殊的语法,进行替换

    html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <!--{{item}}设置一个表示-->
    <h1>{{item}}</h1>
    </body>
    </html>

    逻辑处理文件controller.py

    #!/usr/bin/env python
    #coding:utf-8
    import os                                                 #引入os模块
    import time                                               #引入事件模块
    # 映射文件对应的函数
    def index():                                              #函数返HTML文件内容
        f = open(os.path.join('views','index.html'),'r')      #拼接路径,打开index.html
        data = f.read()                                       #读出html文件内容
        f.close()                                             #关闭打开的文件
        new_data = data.replace("{{item}}",str(time.time()))  #获取系统时间转换成字符串,替换html里的{{item}}
        return new_data
    
    def login():
        f = open(os.path.join('views', 'login.html'),'r')
        data = f.read()
        f.close()
        return data


    2使用开源工具jinja2,遵循其指定语法

    jinja2模块Web框架模块
    Template()方法逻辑处理Web框架
    render()方法设置html可调用python变量
    encode()返回逻辑处理后的网页字符串给浏览器

     首先需要安装jinja2第三方模块

     逻辑处理文件controller.py

    #!/usr/bin/env python
    #coding:utf-8
    import os                                                 #引入os模块
    from jinja2 import Template                               #引入jinja2模块
    # 映射文件对应的函数
    def index():                                              #函数返HTML文件内容
        f = open(os.path.join('views','index.html'),'r')      #拼接路径,打开index.html
        result = f.read()                                     #读出html文件内容
        f.close()                                             # 关闭打开的文件
        template = Template(result)                           #将读出的字符串传入jinja2模块的Template方法逻辑处理网页字符串
        data = template.render(name='John Doe', user_list=['alex', 'eric'])     #render方法向网页字符串添加python可以变量
        return data.encode('utf-8')                           #返回逻辑处理后的字符串给浏览器
    
    def login():
        f = open(os.path.join('views', 'login.html'),'r')
        data = f.read()
        f.close()
        return data

    html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>{{name}}</h1>  <!--{{引用框架逻辑处理设置变量}}-->
    
        <ul>
            {% for item in user_list %} <!--{%可以远行代码块%}-->
            <li>{{item}}</li>
            {% endfor %}
        </ul>
    </body>
    </html>
  • 相关阅读:
    项目部署到tomcat,浏览器能够访问,手机不能访问。
    项目部署到tomcat上
    MySQL触发器的使用
    支付宝接口的使用
    Oracle RAC管理及维护命令详解
    SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用
    Oracle12c中容错&amp;性能新特性之表空间组
    一个典型的多表参与连接的复杂SQL调优(SQL TUNING)引发的思考
    默然回首繁忙而充实的2016
    一副美丽而庞大的SQL TUNING计划美图
  • 原文地址:https://www.cnblogs.com/adc8868/p/6846140.html
Copyright © 2011-2022 走看看