[] Django Web framework nature

@
*
We can interpret it this way: All == Web applications is essentially a socket server ==, and the user's browser is a socket == end == customer service. **

So that we can implement their own Web framework of:

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(9000)
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')       # 响应状态行
    conn.send(b'Hello,world!')
    conn.close()

It can be said on the Web service extensions are essentially out of this dozen lines of code base, this code is their fathers.

A user's browser, enter the URL, the server will send data that the browser will send what data? How hair? Who fixed this? You website is this provision, according to his Web site that he that provision, which the Internet can play it?
Therefore, there must be a uniform rule, so that we send messages, receive messages when there is a format basis, not just to write.
This rule is the HTTP protocol, the browser sends a request message after Ye Hao, the server replies response information worth mentioning, should follow this rule.
The main provisions of the HTTP protocol communication format between the client and server, HTTP protocol that is how the message format prescribed it?

Let us first print what messages we received in service termination are:

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(9000)
    print(data)  # 将浏览器发来的消息打印出来
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    conn.send(b'Hello,world!')
    conn.close()

Output is as follows:

b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n\r\n'

Then we will see a response to the information we access the blog official web browser of what is received, information about the response can be seen in the network browser tab Debug window:
Here Insert Picture Description
We need to find messages sent and received in accordance with a certain format, here it is necessary to know the HTTP protocol.

Each HTTP requests and responses follow the same format, an HTTP Header and Body comprising two portions, wherein Body is optional. Header HTTP response has a == Content-Type == show content format of the response. As == text / html == represent HTML page.

HTTP GET request format:
Here Insert Picture Description

HTTP response format:
Here Insert Picture Description
****

Return different content depending on the path

regular version

== idea: to get the route request URL from which the request data, and make a judgment == take the path.

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行

    if url == '/index':
        response = 'index'
    elif url == '/home':
        response = 'home'
    else:
        response = '404 not found!'

    conn.send(bytes(response, encoding='UTF-8'))
    conn.close()

The code above solves return different content for different URL path requirements.
But the problem again, if there are many paths to determine how to do it? Do you want to write one by one if the judge?
The answer is no, we have a more clever way:

Function version

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


def home(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行

    if url == '/index':
        response = index(url)
    elif url == '/home':
        response = home(url)
    else:
        response = b'404 not found!'

    conn.send(response)
    conn.close()

The above code looks or to write one by one to determine if, how do?
As long as ideology is not landslide, the method is better than the problem more, walk!

Premium function

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


def home(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


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

while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    # 把收到的字节类型的数据转换成字符串
    data_str = ?tr(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行


    # -------关键就在于这一坨代码-------
    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'


    conn.send(response)
    conn.close()

The perfect solution different URL to return different content issues.
But we just want to return several strings, we want to give the browser returns the full HTML content, how should we do this? Then go!
***

Return specific HTML file

First of all we need to know: == No matter what, the last byte of data is converted into == sent out.
So, we can open the HTML file in binary form, read the data file, and then sent to the browser.

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    with open('index.html', 'rb') as f: return f.read()


def home(url):
    with open('home.html', 'rb') as f: return f.read()


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

while True:
    # ------------ 建立连接 接收消息 ------------
    conn, addr = sk.accept()
    data = conn.recv(8096)

    # ------------ 对客服端发来的消息做处理 ------------
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割

    # ------------ 业务逻辑处理部分 ------------
    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'

    # ----------- 回复响应消息 -----------
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行
    conn.send(response)
    conn.close()

Yes, there are problems!
This page is able to show up, but are static ah, the content of the page does not change, we want a dynamic website!
***

Make up dynamic web pages

== idea: using string replacement functions to achieve this demand ==.
Here we are using the current time to simulate the dynamic data

login function corresponds to the file:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>login</title>
</head>
<body>
<h1>登录页面</h1>
<h1>This is login page!</h1>
<a href="https://blog.csdn.net/qq_41964425/article/category/8083068" target="_blank">CSDN</a>

<p>时间:@@xx@@</p>    <!--提前定义好特殊符号-->
</body>
</html>

Python code:

from time import strftime
from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    with open('index.html', 'rb') as f: return f.read()


def home(url):
    with open('home.html', 'rb') as f: return f.read()


# 实现动态网页
def login(url):
    now_time = str(strftime('%F %T'))
    with open('login.html', 'r', encoding='UTF-8') as f:
        s = f.read()
    # 在网页中定义好特殊符号,用动态的数据去替换定义好的特殊符号
    s = s.replace('@@xx@@', now_time)
    return bytes(s, encoding='UTF-8')


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

while True:
    # ------------ 建立连接 接收消息 ------------
    conn, addr = sk.accept()
    data = conn.recv(8096)

    # ------------ 对客服端发来的消息做处理 ------------
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割

    # ------------ 业务逻辑处理部分 ------------
    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'

    # ----------- 回复响应消息 -----------
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行
    conn.send(response)
    conn.close()

Servers and applications

For the python web development program, the general will be divided into two parts: the server and applications == ==.

Server program is responsible for encapsulating socket server, and request arrives, various data request collation; is responsible for a specific application logic.

In order to facilitate the development of applications, there have been numerous Web frameworks such as: Django, Flask, web.py and so on. Different frameworks have different ways of development, but in any case, have developed applications and server programs cooperate to provide services for users.

Thus, the server program will need to provide different support for different frame. Such chaos or whether it is for a server framework, are not good.

At this time, standardization becomes particularly important, we can set up a standard, as long as the server supports this standard, the framework also supports this standard, then they can be used together. Once the standard is determined, each of the parties to achieve.

WSGI (Web Server Gateway Interface) is a specification. It defines the interface between the format written in Python Web applications and Web server program, decoupling between Web applications and Web server program.

Commonly used WSGI server has uwsgi, Gunicorn. WSGI server independent Python standard library called wsgiref, == Django development environment is the use of this module to do the server. ==

wsgiref module

Use wsgiref module replaces write our own Web frameworks socket server part:

login function corresponds to the file:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>login</title>
</head>
<body>
<h1>登录页面</h1>
<h1>This is login page!</h1>
<a href="https://blog.csdn.net/qq_41964425/article/category/8083068" target="_blank">CSDN</a>

<p>时间:@@xx@@</p>    <!--提前定义好特殊符号-->
</body>
</html>

Python code:

from time import strftime
from wsgiref.simple_server import make_server


# 将返回不同的内容部分封装成函数
def index(url):
    with open('index.html', 'rb') as f: return f.read()


def home(url):
    with open('home.html', 'rb') as f: return f.read()


def login(url):
    """实现动态网页"""
    now_time = str(strftime('%F %T'))  # 获取当前格式化时间
    with open('login.html', 'r', encoding='UTF-8') as f:
        s = f.read()
    # 在网页中定义好特殊符号,用动态的数据去替换定义好的特殊符号
    s = s.replace('@@xx@@', now_time)
    return bytes(s, encoding='UTF-8')


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


def run_server(environ, start_response):
    # 设置HTTP响应的状态码和头消息
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])
    url = environ['PATH_INFO']  # 取到用户输入的url

    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'

    return [response, ]


if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8080, run_server)
    print('Wsgiref has started...')
    httpd.serve_forever()

Guess you like

Origin www.cnblogs.com/gqy02/p/11304518.html