今日学习目标
- 搞懂什么是web框架,认识Django框架
文章目录
学习内容
- 个人手写web框架(简易)
- 动静态网页
- 个人总结结构web框架
- python主流web框架
- django框架简介
一、个人手写web框架(简易)
什么是web框架
web框架:将前端、数据库整合到一起的基于互联网传输的python代码
web框架也可以简单的理解为是软件开发架构里面的’服务端’
1.搭建简易版本服务端
socket模块
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8082))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024)
sock.send(b'404 error')
sock.close()
分析
此时利用IP和端口去浏览器链接的话会报错,无法建立链接。这时候就想到了之前学习网络编程时,提到的HTTP协议。HTTP协议主要规定了客户端和服务器之间的通信格式,这样就可以进一步改进我们自己的服务端了。
2.遵循HTTP协议,改进服务端
import socket
sock = socket.socket()
sock.bind(('127.0.0.1', 8082))
sock.listen()
while True:
sock, addr = sock.accept()
data = conn.recv(8096)
# 给回复的消息加上响应状态行
sock.send(b"HTTP/1.1 200 OK\r\n\r\n")
sock.send(b"OK")
sock.close()
分析
此时就可以完成服务端向浏览器发送信息了,但是我们在平时使用浏览器时,当我们点击某个导航时,服务器会发送对应信息到浏览器上。为了让我们的服务端可以拥有这个功能,我们就要先想如何获取用户请求,然后给予相应的回应。
思路
前端其实可以将用户信息返回给后端服务器的,一般网站大部分都是将信息加在URL后面,然后根据HTTP协议提供给服务器,所以我们就可以去截取信息,去做出回应。
3.基于不同的后缀响应不同的内容
如何获取用户输入的url后缀>>>:HTTP请求数据
利用字符串切割和索引取值获取相应数据
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8082))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024)
# 将请求相关数据先转成字符串
data_str = data.decode('utf8') # 'GET /login HTTP/1.1\r\nHost: 127.0.0.1:8081\r\n......'
sock.send(b'HTTP1.1 200 OK\r\n\r\n')
# 然后去字符串中截取出我们需要的内容(按照空格切割字符串 获取第二个元素即可)
current_path = data_str.split(' ')[1]
# 根据后缀的不同返回不同的内容
if current_path == '/login':
sock.send(b'hello login!!!')
elif current_path == '/register':
sock.send(b'hello register')
else:
sock.send(b'404 error')
sock.close()
分析
上述框架缺陷:
1.服务端起始代码过于重复
2.针对HTTP请求数据没有完善的处理方式
3.并发量问题
基于wsgiref模块
针对上述问题,python提供了去解决它的模块wsgiref模块,并且利用函数封装,来优化代码编写。
from wsgiref.simple_server import make_server
# 将返回不同的内容部分封装成函数
def index(url):
s = "这是{}页面!".format(url)
return bytes(s, encoding="utf8")
def home(url):
s = "这是{}页面!".format(url)
return bytes(s, encoding="utf8")
# 定义一个url和实际要执行的函数的对应关系
list1 = [
("/index", index),
("/home", home),
]
def run_server(environ, response):
"""
:param request: 请求相关的数据
:param response: 响应相关的数据
:return: 返回给客户端的展示数据
"""
response('200 OK', []) # 固定编写 无需掌握
current_path = request.get("PATH_INFO")
func = None # 定义一个保存将要执行的函数名的变量
for i in list1:
if i[0] == current_path:
func = i[1]
break
if func:
response = func(current_path)
else:
response = b"404 not found!"
# 返回具体的响应消息
conn.send(response)
conn.close()
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
二、动静态网页
- 静态网页
页面上的数据是直接写死的 万年不变
eg:上述项目中编写的 error.html func.html - 动态网页
页面上的数据是通过代码动态获取的 实时可变
eg:
1.页面上展示当前时间(后端获取传递给前端界面)
2.页面上展示数据库数据(后端链接数据库查询数据再传递给页面)
案例1: 页面上展示当前时间
def get_time(request):
# 1.获取当前时间
import time
c_time = time.strftime('%Y-%m-%d %X')
# 2.读取html文件
with open(r'templates/get_time.html','r',encoding='utf8') as f:
data = f.read()
# 3.思考:如何给字符串添加一些额外的字符串数据>>>:字符串替换
new_data = data.replace('asdaksdjal',c_time)
return new_data
案例2: 将字典传递给页面 并且在页面上 还可以使用字典的操作方法
这时候就要提到python提供的jinja2模板语法,它的作用就是去实现动态化网页数据
jinja2模块
-
第三方模块
pip3 install jinja2
-
功能介绍
在编写前后端不分离项目的时候 可以使用该模块提供的模板语法简单快速的在html页面是使用类似于后端的代码语法操作数据 -
功能实现
HTML代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>姓名:{{name}}</h1>
<h1>爱好:</h1>
<ul>
{% for hobby in hobby_list %}
<li>{{hobby}}</li>
{% endfor %}
</ul>
</body>
</html>
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"), ]
def home():
with open("home.html", "rb") as f:
data = f.read()
return [data, ]
# 定义一个url和函数的对应关系
URL_LIST = [
("/index/", index),
("/home/", home),
]
def run_server(environ, response):
response('200 OK', []) # 固定编写 无需掌握
current_path = request.get("PATH_INFO")
func = None # 定义一个保存将要执行的函数名的变量
for i in list1:
if i[0] == current_path:
func = i[1]
break
if func:
response = func(current_path)
else:
response = b"404 not found!"
# 返回具体的响应消息
conn.send(response)
conn.close()
if __name__ == '__main__':
httpd = make_server('127.0.0.1', 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
个人总结结构web框架
-
urls.py
后缀与函数名对应关系
(‘/index’,register)
后缀专业名词称之为’路由’
函数名专业名词称之为’视图函数’
urls.py专业名词称之为’路由层’ -
views.py
专门编写业务逻辑代码
可以是函数 也可以是类
函数专业名词称之为’视图函数’
类专业名词称之为’视图类’
views.py专业名词称之为’视图层’ -
templates文件夹
专门存储html文件
html文件专业名词称之为’模板文件’
templates文件夹专业名词称之为’模板层’
框架请求流程
python主流web框架
django
大而全 自带的功能非常的多 但是有时候会略显笨重
类似于’航空母舰’
flask
小而精 自带的功能非常的少 但是第三方模块非常的多
类似于’游骑兵’
#flask的第三方模块加到一起甚至比django还多 并且也越来越像django
#flask由于过多的依赖于第三方模块 有时候也会受制于第三方模块
tornado
异步非阻塞框架 速度极快 甚至可以用于充当游戏服务器
还有一些占比较小 但是也很厉害的框架
fastapi、sanic…
django框架简介
版本问题
django3.X:默认支持异步功能
django2.X:默认不支持异步
django1.X:默认不支持异步
django1.11.X LTS 2018年发布
django2.2.X LTS 2020年发布
启动问题
django启动可能报错的原因
1.计算机名称不能含有中文
直接修改即可
2.不同版本的解释器可能会报错
找到报错信息的最后一行提示对应的代码 删除源文件逗号即可
eg: 解释器推荐使用python3.6 几乎不会报错
解释器如果是高版本使用django1.11可能会报错
解释器如果是低版本使用django2、3也可以报错
3.项目中所有的文件名称最好使用英文
4.一个pycharm窗口尽量就是一个完整的项目 不要嵌套
下载
pip3 install django==1.11.11
django基本使用
验证是否下载成功
cmd窗口直接输入django-admin有反应就是成功了
命令操作django
- 创建django项目
django-admin startproject 项目名(mysite) - 启动django项目
cd 项目名(mysite)
python3 manage.py runserver IP:PORT - 创建app应用
python3 manage.py startapp 应用名(app01)
‘’‘命令行无法自动创建模板文件夹 需要自己执行命令创建’‘’
pycharm操作django
- new project
选择django 填写应用即可
‘’‘pycharm默认会自动帮你创建模板文件夹 并提供创建一个app的功能’‘’ - 创建更多的app
tools
run manage.py task 命令自动提示 - 启动项目
直接点击绿色箭头
还可以修改端口号 edit configurations
django主要文件介绍
- 项目文件名
-
与项目名同名文件夹
settings.py 项目配置文件
urls.py 路由层 -
manage.py
django入口文件 很多命令都需要该文件支持 -
db.sqlite3
django启动之后才会生成的文件 其实就是django自带的小型数据库 -
templates文件夹
模板层 -
应用文件夹
migrations文件夹 数据迁移记录(后续讲解)
admin.py django自带的后台管理(后续讲解)
apps.py 用于app的注册(后续讲解)
models.py 专门用于操作数据库(后续讲解 很重要)
views.py 视图层
-