康少帶你手擼簡易版本的django框架

純手擼Django框架html

https協議:前端

四大特性:python

1.HTTP是一個基於TCP/IP通訊協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。mysql

2.基於請求響應web

3.HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。sql

4.HTTP是無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。數據庫

數據格式
     請求:
        請求首行GET  url HTTP/1.1
        請求頭(一大堆k,v的鍵值對組成)
        \r\n
        請求體
     
     響應:
        同上
  響應狀態碼
     1XX:服務器已接收到你的數據正在處理,你能夠繼續提交數據
     2XX:請求成功,返回相應數據
     3XX:重定向
     4XX:請求不存在(404)
     5XX:服務器錯誤

基於socket寫一個web應用服務器

import socket


"""
請求首行
b'GET / HTTP/1.1\r\n
請求頭(一大堆kv鍵值對)
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
請求體
"""
server = socket.socket()  # 不傳參數默認就是TCP協議
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn, addr = server.accept()  # 阻塞 等待客戶端連接
    data = conn.recv(1024)
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    print(data)
    # 手動處理http數據獲取用戶訪問的路徑
    current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]
    if current_path == '/index':
        # 路由匹配上以後返回index
        # conn.send(b'<h1>index</h1>')
        with open('index.html','rb') as f:
            conn.send(f.read())
    else:
        # 當匹配不上的時候統一返回404
        conn.send(b'404')

    conn.close()

利用 wsgiref 和 jinja2 模塊手擼Django框架app

from wsgiref.simple_server import make_server
from urls import *




def run(env,response):
    """
    :param env: 請求相關的信息
    :param response: 響應相關的信息
    :return:
    """
    print(env)  # 是一個大字典 裏面裝了一堆處理好了的鍵值對數據
    response('200 OK',[('username','jason'),('password','123')])  # 固定寫法 後面列表裏面一個個元祖會以響應頭kv鍵值對的形式返回給客戶端
    # 獲取用戶訪問的路徑
    current_path = env.get('PATH_INFO')
    # if current_path == '/index':
    #     return [b'index']
    # elif current_path == '/login':
    #     return [b'login']
    # 定義一個存儲函數名的變量名
    func = None
    # 循環比對路由與試圖函數的映射關係
    for url_map in urls:  # url_map = ('/index',index)
        if current_path == url_map[0]:
            func = url_map[1]
            # 只要匹配成功 直接結束循環
            break
    if func:
        res = func(env)
    else:
        res = error(env)
    return [res.encode('utf-8')]

if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run)
    server.serve_forever()

urls.py框架

from views import *

urls = [
    ('/index',index),
    ('/login',login),
    ('/reg',reg),
    ('/get_time',get_time),
    ('/get_user',get_user),
    ('/get_db',get_db),
]

view.py

import time
from jinja2 import Template
import pymysql


def index(env):
    return 'index'

def login(env):
    return 'login'

def reg(env):
    return 'reg'

def get_time(env):
    # 先獲取當前時間
    current_time = time.strftime('%Y-%m-%d %X')
    # 打開html文件讀取內容返回給客戶端
    with open(r'templates/get_time.html','r',encoding='utf-8') as f:
        data = f.read()
    # 由於是以r模式打開的文件,全部獲取到的內容就是一堆字符串
    res = data.replace('@@time@@',current_time)  # 字符串的替換
    return res

def get_user(env):

    with open(r'templates/get_user.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    # 將字典傳遞給前端頁面 前端經過變量名user_dic就能夠獲取到該字典
    return tmp.render(user_dic={'name':"jason",'password':'123'})


def get_db(env):
    # 鏈接數據庫 獲取數據 渲染到前端頁面
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'day54',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from userinfo')
    user_dict= cursor.fetchall()  # [{},{},{},{}]
    with open(r'templates/get_db.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    return tmp.render(user_dict=user_dict)

def error(env):
    return '404 error'

流程圖:

​ 模板語法

{{}}  變量相關
   {%%}  邏輯相關
      {{ data }}
      {{ data.name }}
      {{ data['name'] }}
      {{ data.get('name') }}
  {% for user_dict in user_list%} [{},{},{}]
     {{ user_dict }}
  {% endfor %}
相關文章
相關標籤/搜索