首页 > 其他 > 详细

康少带你手撸简易版本的django框架

时间:2019-06-05 21:53:49      阅读:71      评论:0      收藏:0      [点我收藏+]

纯手撸Django框架

https协议:

四大特性:

1.HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

2.基于请求响应

3.HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

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框架

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 %}

康少带你手撸简易版本的django框架

原文:https://www.cnblogs.com/ZKPython/p/10981762.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!