加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Django:web框架本质

发布时间:2020-12-15 17:16:11 所属栏目:大数据 来源:网络整理
导读:一,web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 这样我们就可以自己实现Web框架了。 1,自定义web框架 sk =span style="color: #000000" socket.socket() sk.bind(( span style="color: #

一,web框架本质

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

1,自定义web框架

sk =<span style="color: #000000"> socket.socket()
sk.bind((
<span style="color: #800000">"<span style="color: #800000">127.0.0.1<span style="color: #800000">",80<span style="color: #000000">))
sk.listen()

<span style="color: #0000ff">while<span style="color: #000000"> True:
conn,addr =<span style="color: #000000"> sk.accept()
data = conn.recv(8096<span style="color: #000000">)
conn.send(b<span style="color: #800000">"<span style="color: #800000">OK<span style="color: #800000">"<span style="color: #000000">)
conn.close()

2,HTTP协议

每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。 HTTP响应的Header中有一个?表明响应的内容格式。如?表示HTML网页。

1)HTTP GET请求的格式:

GET /path HTTP/1.1

使用?分隔多个header

2)HTTP POST请求格式:

POST /path HTTP/1.1

当遇到连续两个?时,表示Header部分结束了,后面的数据是Body。

3)HTTP响应的格式:

200

3,根据不同的路径返回不同的内容

"""根据URL中不同的路径返回不同的内容--函数版"""

import socketsk = socket.socket()sk.bind(("127.0.0.1",8080)) # 绑定IP和端口sk.listen() # 监听

# 将返回不同的内容部分封装成函数def index(url): s = "这是{}页面!".format(url) return bytes(s,encoding="utf8")

def home(url): s = "这是{}页面!".format(url) return bytes(s,encoding="utf8")

while 1: # 等待连接 conn,add = sk.accept() data = conn.recv(8096) # 接收客户端发来的消息 # 从data中取到路径 data = str(data,encoding="utf8") # 把收到的字节类型的数据转换成字符串 # 按rn分割 data1 = data.split("rn")[0] url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 conn.send(b'HTTP/1.1 200 OKrnrn') # 因为要遵循HTTP协议,所以回复的消息也要加状态行 # 根据不同的路径返回不同内容,response是具体的响应体 if url == "/index/": response = index(url) elif url == "/home/": response = home(url) else: response = b"404 not found!"

conn.send(response) conn.close()

4,返回具体的HTML页面

<span style="color: #0000ff">import<span style="color: #000000"> socket
<span style="color: #0000ff">import<span style="color: #000000"> time

sk =<span style="color: #000000"> socket.socket()
sk.bind((<span style="color: #800000">"<span style="color: #800000">127.0.0.1<span style="color: #800000">",8080)) <span style="color: #008000">#<span style="color: #008000"> 绑定IP和端口
sk.listen() <span style="color: #008000">#<span style="color: #008000"> 监听

<span style="color: #008000">#<span style="color: #008000"> 将返回不同的内容部分封装成函数
<span style="color: #0000ff">def<span style="color: #000000"> index(url):
with open(<span style="color: #800000">"<span style="color: #800000">index.html<span style="color: #800000">",<span style="color: #800000">"<span style="color: #800000">r<span style="color: #800000">",encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">"<span style="color: #000000">) as f:
s =<span style="color: #000000"> f.read()
now =<span style="color: #000000"> str(time.time())
s = s.replace(<span style="color: #800000">"<span style="color: #800000">@@oo@@<span style="color: #800000">",now) <span style="color: #008000">#<span style="color: #008000"> 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号
<span style="color: #0000ff">return bytes(s,encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">"<span style="color: #000000">)

<span style="color: #0000ff">def<span style="color: #000000"> home(url):
with open(<span style="color: #800000">"<span style="color: #800000">home.html<span style="color: #800000">",encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">"<span style="color: #000000">) as f:
s =<span style="color: #000000"> f.read()
<span style="color: #0000ff">return bytes(s,encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">"<span style="color: #000000">)

<span style="color: #008000">#<span style="color: #008000"> 定义一个url和实际要执行的函数的对应关系
list1 =<span style="color: #000000"> [
(<span style="color: #800000">"<span style="color: #800000">/index/<span style="color: #800000">"<span style="color: #000000">,index),(<span style="color: #800000">"<span style="color: #800000">/home/<span style="color: #800000">"<span style="color: #000000">,home),]

<span style="color: #0000ff">while 1<span style="color: #000000">:
<span style="color: #008000">#<span style="color: #008000"> 等待连接
conn,add =<span style="color: #000000"> sk.accept()
data = conn.recv(8096) <span style="color: #008000">#<span style="color: #008000"> 接收客户端发来的消息
<span style="color: #008000">#<span style="color: #008000"> 从data中取到路径
data = str(data,encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">") <span style="color: #008000">#<span style="color: #008000"> 把收到的字节类型的数据转换成字符串
<span style="color: #008000">#<span style="color: #008000"> 按rn分割
data1 = data.split(<span style="color: #800000">"<span style="color: #800000">rn<span style="color: #800000">"<span style="color: #000000">)[0]
url = data1.split()[1] <span style="color: #008000">#<span style="color: #008000"> url是我们从浏览器发过来的消息中分离出的访问路径
conn.send(b<span style="color: #800000">'<span style="color: #800000">HTTP/1.1 200 OKrnrn<span style="color: #800000">') <span style="color: #008000">#<span style="color: #008000"> 因为要遵循HTTP协议,所以回复的消息也要加状态行
<span style="color: #008000">#<span style="color: #008000"> 根据不同的路径返回不同内容
func = None <span style="color: #008000">#<span style="color: #008000"> 定义一个保存将要执行的函数名的变量
<span style="color: #0000ff">for i <span style="color: #0000ff">in<span style="color: #000000"> list1:
<span style="color: #0000ff">if i[0] ==<span style="color: #000000"> url:
func = i[1<span style="color: #000000">]
<span style="color: #0000ff">break
<span style="color: #0000ff">if<span style="color: #000000"> func:
response =<span style="color: #000000"> func(url)
<span style="color: #0000ff">else<span style="color: #000000">:
response = b<span style="color: #800000">"<span style="color: #800000">404 not found!<span style="color: #800000">"

<span style="color: #008000"&gt;#</span><span style="color: #008000"&gt; 返回具体的响应消息</span>

<span style="color: #000000"> conn.send(response)
conn.close()

5,服务器程序与应用程序

对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。

服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。

应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。

这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。

这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。

常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,

1)wsgiref

<span style="color: #0000ff">import<span style="color: #000000"> time
<span style="color: #0000ff">from wsgiref.simple_server <span style="color: #0000ff">import<span style="color: #000000"> make_server

<span style="color: #008000">#<span style="color: #008000"> 将返回不同的内容部分封装成函数
<span style="color: #0000ff">def<span style="color: #000000"> index(url):
with open(<span style="color: #800000">"<span style="color: #800000">index.html<span style="color: #800000">",encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">"<span style="color: #000000">) as f:
s =<span style="color: #000000"> f.read()
now =<span style="color: #000000"> str(time.time())
s = s.replace(<span style="color: #800000">"<span style="color: #800000">@@oo@@<span style="color: #800000">"<span style="color: #000000">,now)
<span style="color: #0000ff">return bytes(s,]

<span style="color: #0000ff">def<span style="color: #000000"> run_server(environ,start_response):
start_response(<span style="color: #800000">'<span style="color: #800000">200 OK<span style="color: #800000">',[(<span style="color: #800000">'<span style="color: #800000">Content-Type<span style="color: #800000">',<span style="color: #800000">'<span style="color: #800000">text/html;charset=utf8<span style="color: #800000">'),]) <span style="color: #008000">#<span style="color: #008000"> 设置HTTP响应的状态码和头信息
url = environ[<span style="color: #800000">'<span style="color: #800000">PATH_INFO<span style="color: #800000">'] <span style="color: #008000">#<span style="color: #008000"> 取到用户输入的url
func =<span style="color: #000000"> None
<span style="color: #0000ff">for i <span style="color: #0000ff">in<span style="color: #000000"> list1:
<span style="color: #0000ff">if i[0] ==<span style="color: #000000"> url:
func = i[1<span style="color: #000000">]
<span style="color: #0000ff">break
<span style="color: #0000ff">if<span style="color: #000000"> func:
response =<span style="color: #000000"> func(url)
<span style="color: #0000ff">else<span style="color: #000000">:
response = b<span style="color: #800000">"<span style="color: #800000">404 not found!<span style="color: #800000">"
<span style="color: #0000ff">return<span style="color: #000000"> [response,]

<span style="color: #0000ff">if <span style="color: #800080">name == <span style="color: #800000">'<span style="color: #800000">main<span style="color: #800000">'<span style="color: #000000">:
httpd = make_server(<span style="color: #800000">'<span style="color: #800000">127.0.0.1<span style="color: #800000">',8090<span style="color: #000000">,run_server)
<span style="color: #0000ff">print(<span style="color: #800000">"<span style="color: #800000">我在8090等你哦...<span style="color: #800000">"<span style="color: #000000">)
httpd.serve_forever()

2)jinja2

从数据库中查询数据,然后去替换我html中的对应内容,然后再发送给浏览器完成渲染。 这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据,模板渲染的工具:?

wsgiref.simple_server jinja2 <span style="color: #0000ff">def<span style="color: #000000"> index():
with open(
<span style="color: #800000">"
<span style="color: #800000">index2.html
<span style="color: #800000">"
,<span style="color: #800000">"<span style="color: #800000">r<span style="color: #800000">"<span style="color: #000000">) as f:
data =<span style="color: #000000"> f.read()
template = Template(data) <span style="color: #008000">#<span style="color: #008000"> 生成模板文件
ret = template.render({<span style="color: #800000">"<span style="color: #800000">name<span style="color: #800000">": <span style="color: #800000">"<span style="color: #800000">Alex<span style="color: #800000">",<span style="color: #800000">"<span style="color: #800000">hobby_list<span style="color: #800000">": [<span style="color: #800000">"<span style="color: #800000">烫头<span style="color: #800000">",<span style="color: #800000">"<span style="color: #800000">泡吧<span style="color: #800000">"]}) <span style="color: #008000">#<span style="color: #008000"> 把数据填充到模板里面
<span style="color: #0000ff">return [bytes(ret,encoding=<span style="color: #800000">"<span style="color: #800000">utf8<span style="color: #800000">"<span style="color: #000000">),]

<span style="color: #0000ff">def<span style="color: #000000"> home():
with open(<span style="color: #800000">"<span style="color: #800000">home.html<span style="color: #800000">",<span style="color: #800000">"<span style="color: #800000">rb<span style="color: #800000">"<span style="color: #000000">) as f:
data =<span style="color: #000000"> f.read()
<span style="color: #0000ff">return<span style="color: #000000"> [data,]

<span style="color: #008000">#<span style="color: #008000"> 定义一个url和函数的对应关系
URL_LIST =<span style="color: #000000"> [
(<span style="color: #800000">"<span style="color: #800000">/index/<span style="color: #800000">"<span style="color: #000000">,]) <span style="color: #008000">#<span style="color: #008000"> 设置HTTP响应的状态码和头信息
url = environ[<span style="color: #800000">'<span style="color: #800000">PATH_INFO<span style="color: #800000">'] <span style="color: #008000">#<span style="color: #008000"> 取到用户输入的url
func = None <span style="color: #008000">#<span style="color: #008000"> 将要执行的函数
<span style="color: #0000ff">for i <span style="color: #0000ff">in<span style="color: #000000"> URL_LIST:
<span style="color: #0000ff">if i[0] ==<span style="color: #000000"> url:
func = i[1] <span style="color: #008000">#<span style="color: #008000"> 去之前定义好的url列表里找url应该执行的函数
<span style="color: #0000ff">break
<span style="color: #0000ff">if func: <span style="color: #008000">#<span style="color: #008000"> 如果能找到要执行的函数
<span style="color: #0000ff">return func() <span style="color: #008000">#<span style="color: #008000"> 返回函数的执行结果
<span style="color: #0000ff">else<span style="color: #000000">:
<span style="color: #0000ff">return [bytes(<span style="color: #800000">"<span style="color: #800000">404没有该页面<span style="color: #800000">",]

<span style="color: #0000ff">if <span style="color: #800080">name == <span style="color: #800000">'<span style="color: #800000">main<span style="color: #800000">'<span style="color: #000000">:
httpd = make_server(<span style="color: #800000">'',8000<span style="color: #000000">,run_server)
<span style="color: #0000ff">print(<span style="color: #800000">"<span style="color: #800000">Serving HTTP on port 8000...<span style="color: #800000">"<span style="color: #000000">)
httpd.serve_forever()

二,Django

1,创建一个Django项目

django-admin startproject mysite

2,运行Django项目

python manage.py runserver 127.0.0.1:8000

3,配置文件

1)模板文件配置:

TEMPLATES =: : [os.path.join(BASE_DIR,)],

2)静态文件配置

STATIC_URL = STATICFILES_DIRS =), ]

在配置文件中暂时禁用csrf中间件,方便表单提交测试

?三,Django基础

django.shortcuts HttpResponse,render,redirect

1,HttpResponse

?内部传入一个字符串参数,返回给浏览器。

<div class="cnblogs_code">


     HttpResponse()

2,render

除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。

将数据填充进模板文件,最后把结果返回给浏览器。(类似于我们上面用到的jinja2)

render(request,,{: ,: [,]})

3,redirect

redirect()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读