Python全栈•Django框架(一)⁃Web框架初识

Web框架初识

一、Web框架本质—自己实现Web框架

1、所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(8192)
    conn.send(b'OK')
    conn.close()

2、增加HTTP协议响应头

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(8192)
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    conn.send(b'OK')
    conn.close()

3、根据用户请求不同的URL返回不同的内容

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))
sk.listen()


# 将不同的页面封装成不同的函数
def index(url):
    page = "这是 {} 页面!".format(url)
    return bytes(page, encoding="utf8")


def home(url):
    page = "这是 {} 页面!".format(url)
    return bytes(page, encoding="utf8")


while True:
    conn, addr = sk.accept()
    data = conn.recv(8192)
    # 根据接收用户的信息获取url路径
    data = str(data, encoding='utf-8')
    data1 = data.split("\r\n")[0]
    url = data1.split()[1]

    # 根据不同的路径返回不同内容
    if url == "/index/":
        response = index(url)
    elif url == "/home/":
        response = home(url)
    else:
        response = b"404 NOT FOUND"

    # 给客户端发送数据
    conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n')
    conn.send(response)
    conn.close()

4、用反射优化请求不同URL返回不同内容

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))
sk.listen()


# 将不同的页面封装成不同的函数
def index(url):
    page = "这是 {} 页面!".format(url)
    return bytes(page, encoding="utf8")


def home(url):
    page = "这是 {} 页面!".format(url)
    return bytes(page, encoding="utf8")


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

while True:
    conn, addr = sk.accept()
    data = conn.recv(8192)

    # 根据接收用户的信息获取url路径
    data = str(data, encoding="utf-8")
    data1 = data.split("\r\n")[0]
    url = data1.split()[1]

    # 根据不同的路径返回不同内容
    func = None
    for i in url_list:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 NOT FOUND"

    # 给客户端发送数据
    conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n')
    conn.send(response)
    conn.close()

5、返回完整的静态HTML

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))
sk.listen()


# 将不同的页面封装成不同的函数
def index(url):
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
    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和实际要执行的函数的对应关系
url_list = [
    ("/index/", index),
    ("/home/", home),
]

while True:
    conn, addr = sk.accept()
    data = conn.recv(8192)

    # 根据接收用户的信息获取url路径
    data = str(data, encoding="utf-8")
    data1 = data.split("\r\n")[0]
    url = data1.split()[1]

    # 根据不同的路径返回不同内容
    func = None
    for i in url_list:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 NOT FOUND"

    # 给客户端发送数据
    conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n')
    conn.send(response)
    conn.close()

6、返回动态的HTML,本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据;模板渲染有个现成的工具:jinja2

import time
import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))
sk.listen()


# 将不同的页面封装成不同的函数
def index(url):
    with open("index.html", "r", encoding="utf8") as f:
        s = f.read()
        now = str(time.asctime(time.localtime(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和实际要执行的函数的对应关系
url_list = [
    ("/index/", index),
    ("/home/", home),
]

while True:
    conn, addr = sk.accept()
    data = conn.recv(8192)

    # 根据接收用户的信息获取url路径
    data = str(data, encoding="utf-8")
    data1 = data.split("\r\n")[0]
    url = data1.split()[1]

    # 根据不同的路径返回不同内容
    func = None
    for i in url_list:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 NOT FOUND"

    # 给客户端发送数据
    conn.send(b'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n')
    conn.send(response)
    conn.close()

7、返回动态的HTML,wsgiref版

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.asctime(time.localtime(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和实际要执行的函数的对应关系
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]
            break
    if func:
        response = func(url)
    else:
        response = b"404 NOT FOUND"
    return [response, ]

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

8、返回动态的HTML,wsgiref + jinja2 版

import time
import jinja2
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.asctime(time.localtime(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")

def person(url):
    with open("person.html", "r", encoding="utf8") as f:
        s = f.read()
         # 生成一个jinja2的Template(模板)对象
        template = jinja2.Template(s)
        data = {"name": "Yang", "hobby_list": ["爱好1", "爱好2", "爱好3"]}
         # 本质上是完成了字符串的替换
        response = template.render(data)
    return bytes(response, encoding="utf8")

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

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]
            break
    if func:
        response = func(url)
    else:
        response = b"404 NOT FOUND"
    return [response, ]

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

9、使用pymysql连接数据库

import time
import jinja2
import pymysql
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.asctime(time.localtime(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")

def person(url):
    with open("person.html", "r", encoding="utf8") as f:
        s = f.read()
        # 生成一个jinja2的Template(模板)对象
        template = jinja2.Template(s)

        conn = pymysql.connect(
            host="127.0.0.1",
            port=3306,
            user="root",
            passwd="",
            db="userinfo",
            charset="utf8"
        )
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        cursor.execute("SELECT name, hobby FROM user")
        user = cursor.fetchone()
        cursor.close()
        conn.close()

        hobby_list = user["hobby"].split()
        user["hobby_list"] = hobby_list

        # 本质上是完成了字符串的替换
        response = template.render(user)
    return bytes(response, encoding="utf8")

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

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]
            break
    if func:
        response = func(url)
    else:
        response = b"404 NOT FOUND"
    return [response, ]

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

10、MVC和MTV模式

  • Django的MTV模式本质是各组件之间为了保持松耦合关系,Django的MTV分别代表: 
    • Model(模型):负责业务对象与数据库的对象(ORM)
    • Template(模版):负责如何把页面展示给用户
    • View(视图):负责业务逻辑,并在适当的时候调用Model和Template
  • 此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template


猜你喜欢

转载自blog.csdn.net/weixin_37973929/article/details/79808475