Django前置知识--手撕框架(一)

简介: Django前置知识--手撕框架(一)

手撕框架

在学Django之前,我们先手撸一个简单的socket框架出来

通过对socket的学习,我们知道网络通信,我们完全可以自己写了,因为socket就是做网络通信用的,

下面我们就基于socket来自己实现一个web框架,写一个web服务端,让浏览器来请求,并通过自己的服务端把页面返回给浏览器,浏览器渲染出我们想要的效果。

web框架的本质及自定义web框架

 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,

基于请求做出响应,客户都先请求,服务端做出对应的响应,按照http协议的请求协议发送请求,

服务端按照http协议的响应协议来响应请求,这样的网络通信,我们就可以自己实现Web框架了。

通过对socket的学习,我们知道网络通信,我们完全可以自己写了,因为socket就是做网络通信用的,

下面我们就基于socket来自己实现一个web框架,写一个web服务端,让浏览器来请求,并通过自己的服务端把页面返回给浏览器,浏览器渲染出我们想要的效果

1、tcp_server端

import socket
tcp_server = socket.socket()
#端口复用
tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
tcp_server.bind(("127.0.0.1",8898))   #绑定本地8898端口,后续用浏览器访问
tcp_server.listen(128)
#获取连接对象和客户端ip和端口
while True:
    conn,adddr = tcp_server.accept()

    # 接收数据
    res = conn.recv(1024)
    print(res.decode())
    # 发送数据
    strvar = "need server?"
    conn.send(strvar.encode())
    conn.close()

#tcp_server.close();

浏览器访问:不通

浏览器访问服务器,会发送http请求报文格式到服务端,在服务端打印

GET / HTTP/1.1 #请求方法,请求协议版本号

Host: 127.0.0.1:8898 #请求服务器的ip和端口

Connection: keep-alive #是否长连接

sec-ch-ua: “Chromium”;v=“112”, “Google Chrome”;v=“112”, “Not:A-Brand”;v=“99”

sec-ch-ua-mobile: ?0

sec-ch-ua-platform: “Windows”

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7

Sec-Fetch-Site: none

Sec-Fetch-Mode: navigate

Sec-Fetch-User: ?1

Sec-Fetch-Dest: document

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9

但我们服务端是基于socket写的,没写应用层协议,因此要写基于http协议的数据格式响应客户端

现在服务端回应客户端只有一句二进制的 need server ?

客户端根本解不开,因此客户端会报错,无效响应。

回应的时候要把回应的数据格式加工好,再发出去

改造服务端

import socket
tcp_server = socket.socket()
#端口复用
tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
tcp_server.bind(("127.0.0.1",8898))
tcp_server.listen(128)
#获取连接对象和客户端ip和端口
while True:
    conn,adddr = tcp_server.accept()
    res = conn.recv(1024)
    print(res.decode())
    # 发送数据,这是基于HTTP协议的报文格式
    strvar = "HTTP/1.1 200 0k\r\n\r\nneed server?"
    conn.send(strvar.encode())
    conn.close()

#tcp_server.close();

此时在通过浏览器访问,就收到服务端信息

现在回复给客户端的是简单的字符串,正常的应该回复页面才对

先创建个简单的页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>个人中心</title>
</head>
<body>
    <h1>欢迎来到32期spa会所</h1>

</body>
</html>

在服务端通过http协议发送给客户端

import socket
tcp_server = socket.socket()
#端口复用
tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
tcp_server.bind(("127.0.0.1",8898))
tcp_server.listen(128)
#获取连接对象和客户端ip和端口
while True:
    conn,adddr = tcp_server.accept()
    # 接收客户端数据
    res = conn.recv(1024)
    print(res.decode())



    with open("beautiful.html","rb") as fp:
        data = fp.read()
    # 发送协议数据
    strvar = "HTTP/1.1 200 0k\r\n\r\n"
    conn.send(strvar.encode())
    # 发送给客户端页面
    conn.send(data)
    conn.close()

#tcp_server.close();

客户端访问,已收到服务端发来的页面

给页面添加点样式和动画效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>个人中心</title>
    <link rel="stylesheet" href="xx.css"> #引入外部样式
</head>
<body>
    <h1>欢迎来到32期spa会所</h1>
    <div class="c1"></div>
    <img src="1.jpg" alt="">
</body>
<script src="xx.js"></script> #引入外部js
</html>

重新运行服务器,在浏览器访问,样式也引入了,js也引入了,但是却不显示效果

这是为啥呢,这是因为浏览器对html从上往下解析

当解析到link时,由于写的是相对路径,

浏览器会从当前浏览器路径

127.0.0.1:8898/xx.css 查找,去请求后台,拿这个文件。

但却没找到,异步发了几个请求

请求 xx.css 1.jpg xx.js 都没找到,所以样式显示不出来

查看客户端请求

点击xx.css,查看请求详情

后台没给浏览器发数据,浏览器拿不到数据就无法渲染代码

浏览器打开网页 另存为

会将本页面的html代码 和外部引入的js文件css文件等都存到本地

这样,在本地通过浏览器访问该页面才能正常显示

本地访问,就相当于上网访问一样的显示效果

浏览器查看网页文件 检查–application-top。里面都有

如果把一块下载下来的js,css文件删除,那么本地访问,也将少了样式

我们自己搭的服务器,通过浏览器访问页面,没样式相当于上面另存为本地的html文件,样式被删除了

所以访问没有样式

客户端发来的请求

请求方法后面是请求路径,当我们访问url只接端口号,后面也没接的时候,请求的就是根路径

然后是要各种外部加载文件的请求

客户端请求什么数据,服务端就应该给客户端什么数据。

服务端要把对应的数据给响应回去,根据客户端的请求,要什么,就响应什么回去

服务端循环回应客户端数据,每次都是一样的,html页面

目前我们服务端的做法是,客户端一次请求,服务端回应一个数据,断开连接

客户端再次请求,服务端又响应一个数据,断开连接

但每次客户端请求的数据不一样,但服务端回应的数据却是一样的,都是html页面

显然这样是不合理的

应该根据不同的请求回复不同的数据

分析:每次请求,就GET后面的路径不一样

我们可以基于不同的路径回复不同的数据

服务端改造如下

import socket

#改造服务端,针对客户端不同的请求,服务端回复不同的内容
tcp_server = socket.socket()
#端口复用
tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
tcp_server.bind(("127.0.0.1",8898))
tcp_server.listen(128)


while True:
    # 获取连接对象和客户端ip和端口
    conn,adddr = tcp_server.accept()
    # 接收客户端数据
    res = conn.recv(1024)
    from_broswer = res.decode()
    #重点在这里,根据客户端请求头 GET / HTTP/1.1  可知,以空格为分隔符,取索引为1的数据,即为客户端请求的服务端内容
    path = from_broswer.split()[1]

  做逻辑判断,针对不同请求,回复给客户端不同数据
   if path == "/":
        with open("beautiful.html", "rb") as fp:
            data = fp.read()
    elif path == "/xx.css":
        with open("xx.css", "rb") as fp:
            data = fp.read()
    elif path == "/1.jpg":
        with open("1.jpg", "rb") as fp:
            data = fp.read()
    elif path == "/xx.js":
        with open("xx.js", "rb") as fp:
            data = fp.read()

    # 发送协议数据
    strvar = "HTTP/1.1 200 0k\r\n\r\n"
    conn.send(strvar.encode())
    # 发送给客户端页面
    conn.send(data)
    conn.close()

#tcp_server.close();

 Django前置知识--手撕框架(二):https://developer.aliyun.com/article/1495503

相关文章
|
22天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
120 45
|
3月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
186 4
|
3月前
|
搜索推荐 前端开发 数据可视化
【优秀python web毕设案例】基于协同过滤算法的酒店推荐系统,django框架+bootstrap前端+echarts可视化,有后台有爬虫
本文介绍了一个基于Django框架、协同过滤算法、ECharts数据可视化以及Bootstrap前端技术的酒店推荐系统,该系统通过用户行为分析和推荐算法优化,提供个性化的酒店推荐和直观的数据展示,以提升用户体验。
158 1
|
9天前
|
Python
Django 框架的路由系统
Django 框架的路由系统
29 6
|
1月前
|
IDE 关系型数据库 MySQL
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
这篇文章是关于如何创建一个Django框架,介绍Django的项目结构和开发逻辑,并指导如何创建应用和编写“Hello, World!”程序的教程。
41 3
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
|
23天前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
34 2
|
1月前
|
开发框架 前端开发 数据库
使用Django框架构建一个完整的Web应用
【10月更文挑战第2天】使用Django框架构建一个完整的Web应用
34 1
|
3月前
|
搜索推荐 前端开发 数据可视化
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
本文介绍了一个基于Python协同过滤算法的旅游景点推荐系统,该系统采用Django框架、MySQL数据库、Bootstrap前端和echarts数据可视化技术,旨在为用户提供个性化的旅游推荐服务,提升用户体验和旅游市场增长。
288 9
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
|
3月前
|
搜索推荐 前端开发 算法
基于用户画像及协同过滤算法的音乐推荐系统,采用Django框架、bootstrap前端,MySQL数据库
本文介绍了一个基于用户画像和协同过滤算法的音乐推荐系统,使用Django框架、Bootstrap前端和MySQL数据库构建,旨在为用户提供个性化的音乐推荐服务,提高推荐准确性和用户满意度。
268 7
基于用户画像及协同过滤算法的音乐推荐系统,采用Django框架、bootstrap前端,MySQL数据库
|
3月前
|
存储 缓存 中间件
Django 框架中 Session 的用法
【8月更文挑战第30天】
38 6