自定义web框架(django)

Django基础了解知识

HTTP协议(超文本传输协议)

HTTP协议

  1. 四大特性

    1. 基于TCP/IP之上作用于应用层
    2. 基于请求响应
    3. 无状态 引申出cookie session token……
    4. 无连接

      长连接 websocket (HTTP协议的大补丁)

  2. 数据格式:
    1. 请求格式

      1. 请求首行(请求方式,协议版本等等)
      2. 请求头(一大堆K:V键值对)
      3. \r\n 或者是\n 总之就是加一个空行
      4. 请求体(真正的数据 发post请求的时候才有 如果是get请求不会有)
    2. 响应格式
      1. 响应首行
      2. 响应头
      3. \r\n 或者是\n总之就是加一个空行
      4. 响应体(真正的数据 发post请求的时候才有 如果是get请求不会有)
    3. 响应状态码
      • 用特定的数字表示一些意思

        • 1XX:服务端已经成功接收到了你的数据 表示数据正在处理 你可以继续提交其他数据
        • 2XX:服务端成功响应(200请求成功)
        • 3XX:重定向(没登录淘宝,点击搜索商品,会跳转到登录页面,这就是重定向)
        • 4XX:请求错误(404 请求资源不存在 403 拒绝访问)
        • 5XX:服务器内部错误(500等)
  3. 请求方式
    • get方式:朝别人要数据
  • post请求:向别人提交数据(eg:用户登录)

    • url:统一资源定位符

自定义web框架

主要是以下两个过程:

  1. 手动书写socket
  2. 手动处理http格式数据
## 说明
'''
我的理解是:
    web框架本质就是一个基于socket的客户端和服务端进行通信,交互的过程,也就是C/S架构,其实由于是通过浏览器向服务端发送请求和响应,所以应该是B/S架构,但是浏览器(Browser)本质也是一个客户端。
    如果按照一般的网络编程套路来,会报错,这是因为浏览器端走的是HTTP协议,但是服务端发过来的数据是基于TCP/UDP协议的,所以就不能识别数据而报错。
    所以我们需要在发消息的时候加一个HTTP的格式标准,这样就可以在浏览器端实现正常打印,     这是由于HTTP和TCP是不同层的协议,首先传输层的是TCP,只负责传输数据,发过去就进行接收打印二进制,但是在服务端发送的是支持TCP协议的,这样在浏览器端就会报错而无法正常显示(因为浏览器支持的是HTTP协议)
'''

## 代码
import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)

"""
请求首行
b'GET /index HTTP/1.1\r\n
请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
DNT: 1\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/77.0.3865.120 Safari/537.36\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\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
Sec-Fetch-Site: none\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
请求体
'

#请求体是空的,因为浏览器发送的是get请求,请求体只在post请求时才会有。
"""

while True:
    conn, addr = server.accept()
    data = conn.recv(1024)
    # print(data)  #打印出来的是浏览器发送过来的HTTP请求数据
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    # conn.send(b'hello')
    data = data.decode('utf-8')
    current_path = data.split('\r\n')[0].split(' ')[1]
    # print(current_path)
    if current_path == '/index': # 如果浏览器上输入的后缀是/index, 那么将.html文件读出来发送过去
        # conn.send(b'index')
        with open(r'index.html','rb') as f:# # 这里面用document.charset看一下网页的编码格式,不然的话可能会乱码。
            conn.send(f.read())
    elif current_path == '/login':
        conn.send(b'login')
    else:
        conn.send(b'404 error')
    conn.close()

类型转换

data = b'hello s11'

# 二进制转字符串
data = str(data, encoding='utf-8')
print(data,type(data))

# 字符串转二进制
data = bytes(data, encoding='utf-8')
print(data,type(data))

基于wsgiref模块

? 什么是wsgi

? 该模块实现了自定义web框架的两个过程

? 根据功能不同拆分成了不同的py文件

? 拆分完成之后 如果想要添加功,仅仅只需要在urls.py以及views.py中修改就可以了

  1. urls.py 路由与视图函数对象关系
  2. views.py 放的是视图函数 (处理业务逻辑的,函数或者类)
  3. templates 模板文件夹 (一堆html文件)
## 基于wsgiref.py

'''
(主要作用就是初始化服务端,然后接受浏览器端发过来的请求,把请求分门别类,传给urls找到对应的视图函数,然后在views中执行相应的视图函数并把结果返回到前端页面)
'''

from wsgiref.simple_server import make_server
from urls import urls
from views import *

def run(env,response):
    """
    :param env: 请求相关的所有数据
    :param response: 响应相关的所有数据
    :return:
    """
    response('200 OK',[])
    print(env)
    current_path = env.get('PATH_INFO')
    # if current_path == '/index':
    #     # 很多业务逻辑代码
    #     return [b'index']
    # elif current_path == '/login':
    #     return [b'login']
    # else:
    #     return [b'404 error']
    # 先定义一个变量名 用来存储后续匹配到的函数名
    func = None
    # for循环 匹配后缀
    for url in urls:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就将匹配到的函数名赋值给func变量
            break  # 主动结束匹配
    # 判断func是否有值
    if func:
        res = func(env)
    else:
        res = error(env)
    return [res.encode('utf-8')]

if __name__ == '__main__':
    server = make_server('127.0.0.1',8081,run)
    # 实时监听该地址  只要有客户端来连接 统一交给run函数去处理
    server.serve_forever()  # 启动服务端

## urls.py
'''
主要作用就是用一个存有元组的列表,实现将前端接收到的后缀名与view中的函数进行对应,其实就相当于一个路由分发器,中转驿站
'''

from views import *

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

# views.py
'''
用于处理业务逻辑,其实就相当于之前写的项目中的interface接口,主要根据前端接收过来的数据 然后执行相应的函数,实现相应的功能,并将结果返回给前端展现出来。
'''

def index(env):
    return 'index'

def login(env):
    return 'login'

def error(env):
    return '404 error'

def xxx(env):
    return 'xxx'

from datetime import datetime

def get_time(env):
    current_time = datetime.now().strftime('%Y-%m-%d %X')
    with open(r'E:\Python11\10月\1018\代码\web框架推导\templates\get_time.html','r',encoding='utf-8') as f:
        data = f.read()
    data = data.replace('$$time$$',current_time)
    return data

from jinja2 import Template

def get_user(env):
    d = {'name':'jason','pwd':'123','hobby':['read','running','music']}
    with open(r'E:\Python11\10月\1018\代码\web框架推导\templates\get_user.html','r',encoding='utf-8') as f:
        data = f.read()
    temp = Template(data)
    res = temp.render(user=d)  # 将字典d传递给前端页面
    # 页面上通过变量名user就能够获取到该字典
    return res

import pymysql

def get_db(env):
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = 'root',
        database = 'hupu',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select * from user_info1"
    cursor.execute(sql)
    res = cursor.fetchall()
    print(res)
    with open(r'E:\Python11\10月\1018\代码\web框架推导\templates\get_db.html','r',encoding='utf-8') as f:
        data = f.read()
    temp = Template(data)
    ret = temp.render(user_list = res)  # 将字典d传递给前端页面 页面上通过变量名user就能够获取到该字典
    return ret

### 前端代码

##get_db.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">用户列表</h1>
            <table class="table table-bordered table-striped table-hover">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>pwd</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user_dict in user_list %}
                        <tr>
                            <td>{{ user_dict.id }}</td>
                            <td>{{ user_dict.name }}</td>
                            <td>{{ user_dict.pwd }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>

</div>
</body>
</html>

## get_time.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
$$time$$
</body>
</html>

## get_user.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p>
</body>
</html>

注意1:

? 上面代码也实现了动静态网页的功能,那么什么是动态网页什么是静态网页呢?

? 静态网页:简单来说就是写死的网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。

? 动态网页:页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。主要体现在两种情况:1. 后端获取当前时间展示到前端;2.后端获取数据库中的数据展示到前端

注意2:

? 如何将后端获取的数据 传递给html页面?

? 后端获取的数据 传递给html页面 专用名词>>>: 模板的渲染

? import jinja2就可以实现上述功能:

pip3 install jinja2

    模板语法(极其贴近python后端语法)
        <p>{{ user }}</p>
        <p>{{ user.name }}</p>
        <p>{{ user['pwd'] }}</p>
        <p>{{ user.get('hobby') }}</p>

        {% for user_dict in user_list %}  ##在前端页面中使用后端的循环语法
            <tr>
                <td>{{ user_dict.id }}</td>
                <td>{{ user_dict.name }}</td>
                <td>{{ user_dict.pwd }}</td>
            </tr>
        {% endfor %}

原文地址:https://www.cnblogs.com/michealjy/p/11703439.html

时间: 2024-08-01 23:22:51

自定义web框架(django)的相关文章

Django【二】自定义web框架

自定义web框架 1.准备登录的html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="icon" href="favicon.ico"> </head> <body> <

python运维开发(十七)----jQuery续(示例)web框架django

内容目录: jQuery示例 前端插件 web框架 Django框架 jQuery示例 dom事件绑定 jQuery事件绑定 jQuery循环break jQuery扩展方法 jQuery自定义扩展的方法 jquery扩展实现基本验证 支持是否为空 长度 正则表达式 定义正则表达式 reg = /正则表达式/ ***** g i m ==> 特殊 利用正则匹配 reg.test(字符串) ***** reg.exec(字符串) 全局 非全局字符串三个方法: search match replac

Python自定义web框架、Jinja2

WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦. python标准库提供的独立WSGI服务器称为wsgiref. 标准Web框架 #!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server def RunServer(environ,

自定义Web框架

Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/usr/bin/env python #coding:utf-8   import socket   def handle_request(client):     buf = client.recv(1024)     client.send

python -- 自定义web框架

在学习自定义web框架之前我们对什么是web框架需要有个清晰的认识,本质上说,web框架就是一个socket Server. 目前常见的动态网站WEB框架前面有WSGI(eg:Django.Flask...)或者是自己写的SOCKET(Tornado),然后交给URL路由系统处理,然后交给某个函数或某个类,然后在模板(常用jinja2)里拿到模板然后把模板和从数据库取出的数据进行混合组成一个字符串然后返回给用户(python3在发送时要byte编码). 这里对WSGI举例说明一下: WSGI是用

python web框架 django 工程 创建 目录介绍

# 创建Django工程django-admin startproject [工程名称] 默认创建django 项目都会自带这些东西 django setting 配置文件 django可以配置缓存 连接数据库 做静态文件处理 找模板 django url 用户访问django程序 会从自己规则做匹配 一旦匹配成功 返回用户数据 没有匹配上不返回 django wsgi python有个自带的wsgi模块 可以写自定义web框架 用wsgi在内部创建socket对象就可以了 自己只写处理函数就可

Web框架——Django笔记

Web框架——Django笔记 MVC和MTV MVC:Model.View.Controller MTV:Model.Template.View Django——MTV 1.创建Django程序   (注:创建前需注意配置Django环境变量,python2.7和3.5环境变量) a.命令(使用cmd命令创建) django-admin startproject mysite      创建project cd mysite python manage.py startapp app01  

Python进阶(三十六)-Web框架Django项目搭建全过程

Python进阶(三十六)-Web框架Django项目搭建全过程 ??IDE说明: Win7系统 Python:3.5 Django:1.10 Pymysql:0.7.10 Mysql:5.5 ??Django 是由 Python 开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站! Django 特点 强大的数据库功能 用python的类继承,几行代码就可以拥有一个丰富,动态的数据库操作接口(API),如果需要你也能执行SQL语句. 自带的强大的后台功能 几行简单的代码就让你的网

Django(一)自定义web框架

https://www.cnblogs.com/yuanchenqi/articles/6083427.htm 一 什么是web框架 框架,即framework, 特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. import socket def handle_request(client): buf