热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Web框架初识以及Django框架简介

内容概要原始web框架wsgiref功能模块主要文件与代码封装动静态网页模板语法简介python三大主流web框架Django简介以及基本操作Django必会三板斧内容详细原始we

内容概要

  • 原始web框架

  • wsgiref 功能模块

  • 主要文件与代码封装

  • 动静态网页

  • 模板语法简介

  • python三大主流web框架

  • Django 简介以及基本操作

  • Django 必会三板斧


内容详细

原始web框架

python 进行网络编程可以用 socket 模块

可以把web应用理解为一个 socket 服务端,而用户浏览器是一个 socket 客户端

自定义web框架:

import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
sock, addr = server.accept()
data = sock.recv(10000)
sock.send(b'HTTP/1.1 200')
sock.close()
server.close()

Web服务本质上都是在这十几行代码基础上扩展出来的

data 是浏览器发送给后端的请求数据:

b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nsec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: "Windows"\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36\r\nAccept: 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.9\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCOOKIE: _ga=GA1.4.755355248.1635858969; csrftoken=hP3rSmCtH1jKsiUhEC2ufs3p0q3F08TDvpNsftS78IEQqWvnAWWHO2FhnLtKfhMe; sessiOnid=cp7co0il32xqfcmdmu5dpxjdphe9oaj9\r\n\r\n'

在应用层上,浏览器与服务端数据交互遵循的是 HTTP 协议

请求数据:

image

服务端响应给浏览器的数据信息:(需要点击view source)

image

在浏览器发送的请求数据中,包括了请求首行中的请求方式,也包括了请求头中的路由(资源地址)和协议名称,服务端接收到请求数据之后需要对数据进行进一步分析,给浏览器响应回相应的网页资源

image

下面,直接书写纯手撸web框架的最终版本:

"""
根据URL中不同的路径返回不同的内容--函数进阶版
返回HTML页面
让网页动态起来
"""
import socket
import time
sk = socket.socket()
sk.bind(("127.0.0.1", 8080)) # 绑定IP和端口
sk.listen() # 监听
# 将返回不同的内容部分封装成函数
def index(url):
with open("index.html", "r", encoding="utf8") as f:
s = f.read()
now = str(time.time())
s = s.replace("@@oo@@", now) # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号
return bytes(s, encoding="utf8")
def home(url):
with open("home.html", "r", encoding="utf8") as f:
s = f.read()
return bytes(s, encoding="utf8")
# 定义一个url和实际要执行的函数的对应关系
list1 = [
("/index/", index),
("/home/", home),
]
while 1:
# 等待连接
conn, add = sk.accept()
data = conn.recv(8096) # 接收客户端发来的消息
# 从data中取到路径
data = str(data, encoding="utf8") # 把收到的字节类型的数据转换成字符串
# 按\r\n分割
data1 = data.split("\r\n")[0]
url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径
conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因为要遵循HTTP协议,所以回复的消息也要加状态行
# 根据不同的路径返回不同内容
func = None # 定义一个保存将要执行的函数名的变量
for i in list1:
if i[0] == url:
func = i[1]
break
if func:
respOnse= func(url)
else:
respOnse= b"404 not found!"
# 返回具体的响应消息
conn.send(response)
conn.close()

在该版本的web框架中,web服务可以根据不同的路径返回不同的内容,并且能直接以文件操作的方式返回HTML页面。


wsgiref 功能模块

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

wsgiref 和 uwsgi 是实现这种协议的功能模块

wsgiref 是 Python标准库提供的独立WSGI服务器,Django开发环境用的就是这个模块来做服务器。

利用wsgiref模块来替换我们自己写的web框架的socket server部分:

"""
根据URL中不同的路径返回不同的内容--函数进阶版
返回HTML页面
让网页动态起来
wsgiref模块版
"""
import time
from wsgiref.simple_server import make_server
# 将返回不同的内容部分封装成函数
def index(url):
with open("index.html", "r", encoding="utf8") as f:
s = f.read()
now = str(time.time())
s = s.replace("@@oo@@", now)
return bytes(s, encoding="utf8")
def home(url):
with open("home.html", "r", encoding="utf8") as f:
s = f.read()
return bytes(s, encoding="utf8")
# 定义一个url和实际要执行的函数的对应关系
list1 = [
("/index/", index),
("/home/", home),
]
def run_server(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息
url = environ['PATH_INFO'] # 取到用户输入的url
func = None
for i in list1:
if i[0] == url:
func = i[1]
break
if func:
respOnse= func(url)
else:
respOnse= b"404 not found!"
return [response, ]
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()

主要文件与代码封装

上面封装好的 web 框架代码,为了解耦合,增强他们的拓展性,可以根据不同功能存放到不同的文件中

处理业务逻辑的代码放在 views.py 文件中:

image

做路由分发的代码放在 urls.py 文件中:

image

启动服务端的代码放在启动文件中:

image


动静态网页

静态网页: 前端页面上的数据全都是展示之前准备好的,固定不变的,数据不能进行实时更改

动态页面: 前端页面上的数据可以实时获取并展示,可以从后端获取数据,也可以从数据库中查询获取到展示在页面上

静态网页:

1、不含后台收据库,不可交互。静态网页内容相对固定,容易被搜索引擎检索,且不需要连接数据库,因此响应速度较快。适合于做展示作品的网站。

2、静态网页并不是静止不动的,它也可以出现各种动态的效果,如 GIF 动画、FLASH、滚动字幕等。它的更新和维护也非常麻烦。

3、静态网页服务的实现首先需要客户机通过浏览器向服务器发出请求,然后服务器接受请求并根据请求从服务器端的网页中找到对应的页面,最后返回给客户机浏览器。这个过程中所发送的页面都是事先编辑好的,它并不能自动生成。

动态网页:

1、动态网页是基本的 HTML 语法规范与 PHP、Java、Python 等程序语言、数据库等多种技术的融合,可以理解为凡是结合了 HTML 以外的高级程序设计语言和数据库技术进行的网页编程技术生成的网页都是动态网页。动态网页可以很好地实现和用户的交互,可以实现更多的功能,如用户的登录、注册、查询等。

2、动态网页与网页上的各种动画、滚动字幕等视觉上的动态效果没有直接关系,动态网页也可以是纯文字内容的,也可以包含各种动画的内容,只要是采用了动态网站技术(如 PHP、JSP 等)生成的网页都可以称为动态网页。

3、与静态网页的实现方法不同,动态网页服务的实现首先需要客户机向服务器发送请求,然后服务器根据用户请求把动态网页内部的代码先在服务器上进行相应的处理,最后服务器把生成的结果发送给客户机


模板语法简介

从后端获取数据之后,在前端怎么样能方便快捷地对数据进行处理并展示出来呢?这里就要使用到模板语法

在 python 中,可以使用模块 jinja2 实现前端页面文档获取后端数据的功能

# 下载
pip install jinja2

前端 HTML 文件:










姓名:{{name}}
爱好:


    {% for hobby in hobby_list %}
  • {{hobby}}

  • {% endfor %}



# {{ }} 可以获取后端的变量
# {% %} 可以在前端实现简单的流程控制代码

后端给前端文件传送数据:

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

python三大主流web框架


1、优缺点对比



  • Django

优点: 体量大、功能齐全,自带功能特别特别多,类似航空母舰

缺点: 有时过于笨重



  • Flask

优点: 小而精,自带功能少,但第三方模块特别多,加起来甚至可以超过Django,也越来越像Django

缺点: 比较依赖第三方开发者



  • tornado

优点: 异步非阻塞,支持高并发,甚至可以用来开发游戏服务器

缺点:


2、功能对比

image


Django 请求生命周期流程图

web服务网关接口

Django使用自带的wsgiref模块

作用:



  • 收到请求时,对http协议格式的请求数据进行解析,并封装成字典格式;

  • 发送响应时,将响应数据封装成符合http协议格式的数据。

    补充:

wsgiref模块支持的并发量不大,最大并发量不超过1000;

项目上线后一般会换成uwsgi来提高最大并发量,前面还会加nginx进行反向代理;



  • WSGI,wsgiref 和 uwsgi 是什么关系?

    WSGI是协议,wsgiref和uwsgi是实现该协议的功能模块。



image


Django 简介以及基本操作


1、MTV 模型 与 MVC 模型

MVC模型

Web服务器开发领域里著名的MVC模式,将web应用分为以下三层:



  • 模型(Model)

  • 视图(View)

  • 控制器(Controller)

以上三层之间以一种插件式的、松耦合的方式连接在一起:

模型负责业务对象与数据库的映射(ORM)

视图负责与用户的交互(页面)

控制器接受用户的输入调用模型和视图完成用户的请求。

其示意图如下所示:

MTV模型

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是指:



  • M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。

  • T 代表模板 (Template):负责如何把页面展示给用户(html)。

  • V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template。

Django 使用MTV模型


2、基本操作


在windows cmd命令行界面下操作


切换到响应目录中

创建diango项目:(mysite 是项目名称)

django-admin startproject mysite

切换到 mysite 项目目录中

创建应用:(app01是应用名称)

python manage.py startapp app01

启动django项目:

python manage.py runserver 8080

runserver 默认为本机(127.0.0.1),后面跟的8080为端口号


pycharm 操作


新建项目时选择django 即可

image

新建Django项目的目录名:

image

image


Django 必会三板斧

from django.shortcuts import HttpResponse, render, redirect

HttpResponse

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

例如:

def index(request):
# 业务逻辑代码
return HttpResponse("OK")

render

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

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

例如:

def index(request):
# 业务逻辑代码
return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})

redirect

接受一个URL参数,表示跳转到指定的URL。

例如:

def index(request):
# 业务逻辑代码
return redirect("/home/")

启动Django报错:

Django 启动时报错 “UnicodeEncodeError ...”

报这个错误通常是因为计算机名为中文,改成英文的计算机名重启下电脑就可以了。

Django 启动报错“SyntaxError: Generator expression must be parenthesized”

报这个错很大可能是因为使用了Python3.7.0,而目前(2018-06-12)Python3.7.0和Django还有点兼容性问题,换回Python3.6的环境即可。



推荐阅读
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
author-avatar
NE丰胸茶urghx
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有