文章目录
一.Web应用本质
1.socket本质
二.发送HTTP协议、响应
1.HTTP协议
2.HTTP发送响应
◼ 静态网页
◼ 动态网页
三.jinja2模板渲染
一.Web应用本质
为了了解Django的客户端与服务端的交互原理,我们需要了解Web应用的本质方便以后更加的理解Django原理

在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来。而浏览器和服务器之间的传输协议是HTTP。所以本质上就是:

浏览器发送一个HTTP请求
服务器收到请求,生成一个HTML文档
服务器把HTML文档作为HTTP响应的Body发送给浏览器
浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。
而在http协议中,我们可以用socket来实现

1.socket本质
web服务器本质上可以认为是一段代码,可以不断的处理http协议的网络请求,而http协议可以使用socket实现,并且http协议是一个无状态的协议,即浏览器发起请求,服务器接收请求,然后给浏览器回复数据,然后断开连接;那么可以用socket来实现一个最简单的web服务器。

HTTP:
无状态、短连接
TCP:
不断开(socket连接)
服务器把HTML文档作为HTTP响应的Body发送给浏览器
WEB应用(网站)
浏览器(socket客服端)
在客户端访问网址后,通过ping 网址 转化为ip地址进行访问(默认监听80端口)
浏览器(socket服务端)

  1. 监听ip和端口
  2. 收到客户端传来的数据
  3. 响应客户端,发送响应数据
  4. 断开客户端连接
    示意如下:

import socket
sock = socket.socket()

网页和监听端口(这里先默认本机端口的8080)

sock.bind((‘127.0.0.1’,8080))

等待五个用户

sock.listen(5)

因为socket是TCP协议不断开

while True:
#等待
conn,addr= sock.accept()
# 有人来连接
# 获取用户发送的数据
data = conn.recv(8096)
# 回数据,转字节
conn.send(b’123123’)
# 断开客户端连接
conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
访问127.0.0.1:8080

示意如下:
在这里插入图片描述

二.发送HTTP协议、响应

1.HTTP协议
在html中发送获取数据都遵从着HTTP协议,随着时间的变化一点一点的在改变,直到现在,我们可以通过socket发来的请求打印data来查看http发送的响应数据:

print(data)
#返回
“”"
响应头
状态:200 OK
‘GET /(get请求数据默认放这) HTTP/1.1’
‘Host: 127.0.0.1:8080’
‘User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0’
‘Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8’
‘Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2’
‘Accept-Encoding: gzip, deflate’
‘Connection: keep-alive’
‘Upgrade-Insecure-Requests: 1’

请求体:如果是post请求数据放这

响应体
‘GET /favicon.ico HTTP/1.1’
‘Host: 127.0.0.1:8080’
‘User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0’
‘Accept: image/webp,/
‘Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2’
‘Accept-Encoding: gzip, deflate’
‘Connection: keep-alive’
‘Referer: http://127.0.0.1:8080/’

“”"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
很显然我们上面写的代码没有根据HTTP的协议发送请求,应该遵循HTTP协议,用户在页面上看到的内容”字符串“(看到页面效果,是由浏览器解析出来的)

示意如下:

import socket
sock = socket.socket()

网页和监听端口(这里先默认本机端口的8080)

sock.bind((‘127.0.0.1’,8080))

等待五个用户

sock.listen(5)

因为socket是TCP协议不断开

while True:
#等待
conn,addr= sock.accept()
# 有人来连接
#1. 获取用户发送的数据
data = conn.recv(8096)

# 4. 遵循http协议
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
# 5. 返回数据,转字节
conn.send(b'123123')
# 6. 断开客户端连接
conn.close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

2.HTTP发送响应
但是我们目前怎么样都只有一个页面,不能像其他的网站一样有多个页面,所以我们要从客户端发来的请求中拿到数据在做出响应在返回:

获取用户发送的数据
接收请求传来的数据
分割数据
遵循http协议
返回相应数据,转字节
断开客户端连接
示意如下:

import socket

相应数据函数

def f1(request):
return b"f1"

def f2(request):
return b"f2"

类似django的路由

routers = [
(’/xxx’, f1),
(’/ooo’, f2),
]

主函数

def run():
sock = socket.socket()
# 网页和监听端口(这里先默认本机端口的8080)
sock.bind((‘127.0.0.1’, 8080))
# 等待五个用户
sock.listen(5)
# 因为socket是TCP协议不断开
while True:
# 等待
conn, addr = sock.accept()
# 有人来连接
# 1. 获取用户发送的数据
data = conn.recv(8096)
# 2. 接收请求传来的数据
data = str(data, encoding=‘utf-8’)
# 3. 分割数据,请求头,和请求体
headers, bodys = data.split(’\r\n\r\n’)
temp_list = headers.split(’\r\n’)
# 获取一.get请求 二.访问url 三.请求体
res, url, hea = temp_list[0].split(’ ‘)
func_name = None
# 4. 遵循http协议
conn.send(b’HTTP/1.1 200 OK\r\n\r\n’)
# 这时候打印的就是后缀的值
print(url)
# 遍历路由
for item in routers:
if item[0] == url:
# 判断是否是该url返回函数地址
func_name = item[1]
break
# 判断函数是否存在
if func_name:
response = func_name(data)
else:
response = b"404 not found"

  # 5. 返回相应数据,转字节conn.send(response)# 6. 断开客户端连接conn.close()

if name == ‘main’:
run()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
访问127.0.0.1:8080

示意如下:
在这里插入图片描述

所以通过上面例子我们可以写一个html然后渲染。

◼ 静态网页
因为如果想要数据库实时动态产生,我们需要数据库的帮助,不过在开始介绍前,我们先写静态网页,首先在当前主目录下创建两个文件夹动态网页和静态网页。用于区分一下动态网页和静态网页。

在静态文件/index.html中定义视图如下:

ID 用户名 邮箱
1 root root@qq.com

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 在f1中定义函数如下:

def f1(request)
f=open(‘静态网页/index.html’, ‘rb’)
data=f.read()
f.close()
return data
1
2
3
4
5
访问127.0.0.1:8080/xxx

示意如下:

在这里插入图片描述

◼ 动态网页
在前面的文章有写到操作数据库的方法,种类很多这里我们使用pymysql来实现,如果没看到这里的可以点开链接:点我!!!进行查看。

导入驱动程序
pip install pymysql
1
创建数据库连接
import pymysql

创建连接

conn = pymysql.connect(host=‘127.0.0.1’, port=3306, user=‘root’, passwd=‘xxx’, db=‘myemployees’)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

关闭

cursor.close()
conn.close()
1
2
3
4
5
6
7

在这里我们把/ooo改成/userlist.htm为了告诉大家django的路由和这个很像

routers = [
(’/xxx’, f1),
(’/userlist.htm’, f2),
]
1
2
3
4

在动态网页/userlist.html中定义视图如下:

@@content@@

ID 用户名 邮箱

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 因为返回的是字符串所以我们可以对字符串进行拼接成html看得懂的,然后在从html转化为字节传给浏览器。

在f2中定义函数如下:

def f2(request):

创建连接

conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456',         db='myemployees')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 在数据库查询数据
cursor.execute("SELECT employee_id,first_name,phone_number FROM employees")
# 获取所有查到的数据
user_list = cursor.fetchall()
# 关闭
cursor.close()
conn.close()
# 拼接
content_list = []
for row in user_list:tp = "<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (row['employee_id'], row['first_name'], row['phone_number'])# 添加进来content_list.append(tp)
# 拼接到一起
content = "".join(content_list)
# 打开userlist.html
f = open('动态网页/userlist.html', 'r', encoding='utf-8')
# 获得字符串(模板的渲染)
template = f.read()
# 关闭
f.close()
# 把我之前在html写的@@content@@修改
data = template.replace('@@content@@', content)
# 把写好的字符串转成字节的形式给浏览器渲染成可视化界面
return bytes(data, encoding='utf-8')

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
此时访问127.0.0.1:8080/userlist.htm

示意如下:
在这里插入图片描述

三.jinja2模板渲染
对于上面的一系列操作,相对麻烦,又要替换字符串,转字节,还得自己拼接,这时python中就出来了一个模块jinjia2,它可以帮助我们进行模板的渲染,而渲染的规则要和它一致。

安装jinja2模块
pip install jinja2
1
添加一个路由和函数
routers = [
(’/xxx’, f1),
(’/userlist.htm’, f2),
(’/host.html’,f3),
]
1
2
3
4
5

在动态网页/host.html中定义视图如下:

{% for row in user_list %} {% endfor %}

ID 用户名 邮箱
{{ row.employee_id }} {{ row.first_name }} {{ row.phone_number }}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

在f3中定义函数如下:

from jinja2 import Template

def f3(request):
f = open(‘动态网页/host.html’, ‘r’, encoding=‘utf-8’)
# 获得字符串(模板的渲染)
data = f.read()
# 关闭
f.close()
# 创建连接
conn = pymysql.connect(host=‘127.0.0.1’, port=3306, user=‘root’, passwd=‘123456’, db=‘myemployees’)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 在数据库查询数据
cursor.execute(“SELECT employee_id,first_name,phone_number FROM employees”)
# 获取所有查到的数据
user_list = cursor.fetchall()
# 关闭
cursor.close()
conn.close()
# 使用jinja2渲染
template=Template(data)
data=template.render(user_list=user_list)
# 上传
return data.encode(‘utf-8’)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
此时访问此时访问127.0.0.1:8080/host.html

示意如下:

在这里插入图片描述

python Django之Web框架本质 (2)相关推荐

  1. 西游之路——python全栈——Django的web框架本质

    知识预览 Django基本命令 二 路由配置系统(URLconf) 三 编写视图 四 Template 五 数据库与ORM admin的配置 一 什么是web框架? 框架,即framework,特指为 ...

  2. Python之路--WEB框架本质

    一.本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #coding:utf-8im ...

  3. Python学习-基础篇14 Web框架本质及第一个Django实例

    Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...

  4. 手撸web框架即引入框架思想,wsgierf模块,动静态网页,模板语法jinja2,python三大主流web框架,django安装,三板斧...

    手撸web框架 web框架 什么是web框架? 暂时可理解为服务端. 软件开发架构 C/S架构 B/S架构 # 后端 import socketserver = socket.socket() # 不 ...

  5. Django基础-Web框架-URL路由

    Django基础-Web框架-URL路由 一.Django基础–Web框架 MVC和MTV框架 MVC 把Web应用分为模型(M).视图(V).控制器(C)三层,他们之间以一种插件式的,松耦合的方式联 ...

  6. Django基础---Web框架、URL路由、视图函数、模板系统

    文章目录 Django基础 Django基础---Web框架 MVC和MTV框架 MVC MTV Django下载与安装 基于Django实现一个简单的示例 get请求获取数据 post请求获取数据 ...

  7. py库: django (web框架)

    py库: django (web框架) http://www.imooc.com/learn/736 Python-走进Requests库 http://www.imooc.com/learn/790 ...

  8. python四大主流web框架

    python四大主流web框架 转载自博客:https://www.cnblogs.com/an-wen/p/11330834.html --爱文飞翔 Python 四大主流 Web 编程框架 目前P ...

  9. windows2008R2+IIS部署python Django的web环境

    windows2008R2+IIS部署python Django的web环境 这篇文章写得非常好,非常仔细,作者把所有的坑都明确标识出来,可以少走很多弯路.感谢作者 潇洒哥Kahn 的辛苦付出. 这里 ...

最新文章

  1. 自动化测试框架设计模式
  2. tf.nn.softmax_cross_entropy_with_logits 和 tf.contrib.legacy_seq2seq.sequence_loss_by_example 的联系与区别
  3. java发送c语言结构体_C语言中结构体直接赋值?
  4. linux下部署Tesseract OCR及调用
  5. 【Spring框架】全集详解
  6. 手把手教你用WPE“修改”各种魔兽SF
  7. 如何生成唯一的Android设备ID?
  8. 计算机组装主板插线图,电脑组装之主板接口线缆怎么安装【图解教程】
  9. ES3、ES5、ES6、ES2016、ES2017、ES2018、ES2019
  10. 一、物流的基本概念|1.1物流的定义及作用
  11. 第一章 【教育基础知识和基本原理】
  12. Jmeter 压测和AB压测的比较
  13. 数据分析案例-数据科学相关岗位薪资可视化分析
  14. 艾媒咨询:2015年度中国智能路由器市场监测报告
  15. 前端大屏数据可视化示例
  16. dlt645数据读和写
  17. MySQL安装配置(Windows和 Linux )
  18. 北邮 python 学堂在线动态请求页面内容爬取
  19. 安卓APP跳转百度、高德、腾讯地图
  20. tomcat 400错误跳转自定义页面

热门文章

  1. 【李宏毅机器学习】Introduction of ELMO、BERT、GPT(p25) 学习笔记
  2. poj2387TillCowsComHome Dijlstra
  3. LeetCode-20:有效的括号
  4. PreScan中对象沿预设轨迹运动的若干方式介绍
  5. 【python基础知识】Tkinter基础
  6. Spark GraphX相关使用方法
  7. day15 java接口在开发中的作用
  8. python抽奖程序_Python编写抽奖式随机提问程序
  9. html5日程管理系统,有条不紊:四款桌面日程管理软件横测
  10. java 多行文本框_Swing常用组件之多行文本区JTextArea