• django基础之Web框架介绍


    一、web框架介绍:

      什么是web框架:

        所有的web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。这样就可以实现web框架了。

    import socket
    
    sk = socket.socket()
    sk.bind(("127.0.0.1", 80))
    sk.listen(5)
    
    
    while True:
        conn, addr = sk.accept()
        data = conn.recv(8096)
        conn.send(b"OK")
        conn.close()

    总而言之web框架的原理就是这短短的十几行代码,当然用户浏览器向服务端发送数据怎么发,这个怎么定如果谁都能定岂不是乱套了,各有各的规则了,所以就有一个统一的规则,收发数据时候规定了格式,不能随便写,这就是HTTP协议,不管是收数据还是发数据都要按照这个协议的规则来。

    如果想详细了解HTTP:请点击这里

    每个HTTP都包含Header和Body两部分,其中Body是可选的,HTTP响应的响应头(Header)中有content_Type表明响应内容格式。如果响应的是网页,则content-Type的值为text/html

    HTTP的请求方式:

      GET:

    GET /path HTTP/1.1
    header1:v1
    
    header2:v2
    

      POST:

    POST /path HTTP/1.1
    header1:v1
    
    header2:v2
    
    
    
    
    请求体...

    当遇到 时,表示响应头结束了,以 后的数据全属于响应体。

    import socket
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('127.0.0.1', 8000))
    sock.listen(5)
    
    while True:
        conn, addr = sock.accept()
        data = conn.recv(8096)
        conn.send(b"HTTP/1.1 200 OK
    
    ") #此行为响应头
        conn.send(b"OK")    #此行为响应体
        conn.close()
    
    
    #这样就给简单的socket加上了HTTP规则,这样就算实现了一个web框架了

       通过上面用socket实现的简单的web框架足以说明,作为web框架一般分为两个部分:服务程序和应用程序。服务器其实就是起到对socket的封装,并在请求来时对请求的各种数据进行整理。常见的web:Django、Flask、web.py,不同的框架开发方式不同,但是它们开发的应用程序都要和服务器程序配合使用。

      由于框架有多种,服务器程序就需要提供多种不同的支持,这样的话局面会有点混乱,而能给这种情况整一个标准吗?当然有标准啦有了标准框架和服务器都支持这个标准,这样就可以配合工作了,这个标准这么厉害,它是什么呢?
      它就是传说中的WSGI(Web Server Gateway Interface)它就是一种规范,它定义使用Python编写的web应用程序与web服务器程序之间的接口格式,实现应用于服务器程序间的解耦

    常用的WSGI服务器有uwsgi、Gunicorn而Python标准库的独立WSGI服务器叫wsgiref,django就是用这个模块来做服务器的。

    例如:
    
    from wsgiref.simple_server import make_server
    
    
    def run_server(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html;charset=utf8')])  # 设置HTTP响应的状态码和头信息
        return [bytes("<h1>Hello world!</h1>", encoding="utf8"),]
    
    
    if __name__ == '__main__':
        httpd = make_server('', 8000, run_server)
        print("Serving HTTP on port 8000...")
        httpd.serve_forever()

      这样的话是不是有点太简单了点?这也是太简易了,导致用户输入url是无法对url进行处理,那能不能改进一下来接收并处理用户输入的url请求呢

    改进版的简易框架:
    from
    wsgiref.simple_server import make_server def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url if url == "/index/": return [bytes("<h1>这是index页面</h1>", encoding="utf8"), ] elif url == "/home/": return [bytes("<h1>这是home页面</h1>", encoding="utf8"), ] else: return [bytes("404没有该页面", encoding="utf8"), ] if __name__ == '__main__': httpd = make_server('', 8000, run_server) print("Serving HTTP on port 8000...") httpd.serve_forever()

      这不就解决了用户输入URL的问题了吗,但是问题又来了,如果有很多页面呢,挨个判断吗?那也太麻烦了吧,当然会有更好的方法了:

    from wsgiref.simple_server import make_server
    
    
    def index():
        with open("index.html", "rb") as f:
            data = f.read()
        return [data, ]
    
    
    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()
    这不是及解决了不用url全都拿来判断,而且将整个html返回给浏览器了,服务器先打开HTML文件,将其转换为二进制,然后发给浏览器。

       这个页面是不是都写死了啊,那我要在页面上显示一些别的数据咋办呢?整个html文件换掉有点费事吧;怎样解决呢是不是需要做一个动态的HTML呢,那该怎样做呢
      这时候我们需要引进一个新的模块:jinja2   
      jinja2的作用:利用一些特殊的符号来替换要展示的数据,这些特殊符号就是通过ji9nja2来渲染的,说白了jinja2就是一个渲染页面的工具。
      

    下载安装jinja2:
              pip install jinja2

    举例说明:

    <!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>
    index2.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()
    用jinja2来渲染index.html

      对于去数据我们总不能一直把数据写在py文件中吧,我们是不是需要用数据库来存数据呢,数据库怎么用呢

    #一定记着首先要导入
    import 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")
    #这里是执行sql语句,可以将SQL语句写在外面赋值给变量,这里面只写变量名
    user_list = cursor.fetchall()
    cursor.close()
    conn.close()
    pymysql的连接及使用方式

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

  • 相关阅读:
    IIS中的 Asp.Net Core 和 dotnet watch
    net Core 2.0应用程序发布到IIS
    PHP是.NET上的一门开发语言
    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用
    如何快速处理线上故障
    程序员的“认知失调”
    怎么轻松学习JavaScript
    Android-完全退出当前应用程序的四种方法
    Android java.lang.ClassCastException
    Intent传递对象的两种方法(Serializable,Parcelable)
  • 原文地址:https://www.cnblogs.com/kxllong/p/8290499.html
Copyright © 2020-2023  润新知