web框架本质上可以看成是一个功能强大的socket服务端,用户的浏览器可以看成是拥有可视化界面的socket客户端。两者通过网络请求实现数据交互,学者们也可以从架构层面上先简单的将Web框架看做是对前端、数据库的全方位整合
- 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)
- # 此处一会儿需要按照步骤2、3做修改
- sock.send(b'hello world')
- # 服务端响应的数据需要符合HTTP响应格式
- sock.send(b'HTTP1.1 200 OK\r\n\r\n hello world')
- # 将客户端请求相关数据先转成字符串
- data_str = data.decode('utf8')
- # 研究发现可以采用字符串切割获取路由
- 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')
- """
- 纯手撸框架缺陷:
- 1.socket代码过于重复(每次搭建服务端都需要反复造轮子)
- 2.针对HTTP请求数据没有完善的处理方式(目前只能定向切割)
- """
- from wsgiref import simple_server
-
-
- def run(request, response):
- """
- :param request: 请求相关的数据
- :param response: 响应相关的数据
- :return: 返回给客户端的展示数据
- """
- response('200 OK', []) # 固定编写 无需掌握
- return [b'hello world']
-
-
- if __name__ == '__main__':
- server = simple_server.make_server('127.0.0.1', 8080, run)
- '''监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
- server.serve_forever()
- # 模块封装了socket代码并将请求数据处理成诸多k:v键值对
- # run函数体中添加下列代码
- current_path = request.get("PATH_INFO")
- if current_path == '/login':
- return [b'hello login html']
- elif current_path == '/register':
- return [b'hello register html']
- return [b'404 error']
- def register(request):
- return 'register'
-
-
- def login(request):
- return 'login'
-
- def error(request):
- with open(r'templates/error.html', 'r', encoding='utf8') as f:
- return f.read()
-
- urls = (
- ('/login',login),
- ('/register',register)
- )
-
- def run(request, response):
- func_name = None
- for url_tuple in urls:
- if current_path == url_tuple[0]:
- # 先获取对应的函数名
- func_name = url_tuple[1]
- # 一旦匹配上了 后续的对应关系就无需在循环比对了
- break
- # for循环运行完毕之后 func_name也有可能是None
- if func_name:
- res = func_name(request)
- else:
- res = error(request) # 顺手将request也传给函数 便于后续数据的获取
- return [res.encode('utf8')]
views.py
--存储路由与函数对应关系
- # 功能函数
- def register(request):
- return 'register'
-
-
- def login(request):
- return 'login'
-
-
- def index(request):
- return 'index'
-
-
- def error(request):
- with open(r'templates/error.html', 'r', encoding='utf8') as f:
- return f.read()
-urls.py
--存储函数
- from views import *
-
- # 后缀匹配
- urls = (
- ('/register', register),
- ('/login', login),
- ('/index', index),
- )
-server.py
--存储启动及分配代码
- from wsgiref import simple_server
- from urls import urls
- from views import error
-
-
- def run(request, response):
- response('200 OK', [])
- current_path = request.get("PATH_INFO")
- func_name = None
- for url_tuple in urls: # ('/register', register)
- if current_path == url_tuple[0]:
- func_name = url_tuple[1]
- break
- if func_name:
- res = func_name(request)
- else:
- res = error(request)
- return [res.encode('utf8')]
-
-
- if __name__ == '__main__':
- server = simple_server.make_server('127.0.0.1', 8080, run)
- server.serve_forever()
总结:拆分后好处在于要想新增一个功能,只需要在views.py中编写函数,urls.py添加对应关系即可
-templates文件夹
--存储html文件
-static文件夹
--存储html页面所需静态资源(后续详细讲解或自行百度)
- 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('random_str',c_time)
- return new_data
- <h1>展示后端获取的时间数据h1>
- <span>random_strspan>
第三方模块需要先下载后使用
pip3 install jinja2
功能阐述:支持将数据传递到html页面并提供近似于后端的处理方式简单快捷的操作数据
-views.py
- from jinja2 import Template
- def get_dict(request):
- user_dict = {'name': 'jason', 'pwd': 123, 'hobby': 'read'}
- new_list = [11, 22, 33, 44, 55, 66]
- with open(r'templates/get_dict.html', 'r', encoding='utf8') as f:
- data = f.read()
- temp_obj = Template(data)
- res = temp_obj.render({'user':user_dict,'new_list':new_list})
- return res
-templates
--get_dict.html
字典数据展示
{{ user }}
{{ user.name }}
{{ user['pwd'] }}
{{ user.get('hobby') }}
列表数据展示
- {% for i in new_list%}
- 元素:{{ i }}
- {% endfor %}
- urls.py
- 后缀与函数名对应关系
- ('/index',register)
- 后缀专业名词称之为'路由'
- 函数名专业名词称之为'视图函数'
- urls.py专业名词称之为'路由层'
-
- views.py
- 专门编写业务逻辑代码
- 可以是函数 也可以是类
- 函数专业名词称之为'视图函数'
- 类专业名词称之为'视图类'
- views.py专业名词称之为'视图层'
-
- templates文件夹
- 专门存储html文件
- html文件专业名词称之为'模板文件'
- templates文件夹专业名词称之为'模板层'
-
- static文件夹
- 专门存储静态文件资源
- 页面所需css文件、js文件、图片文件、第三方文件可统称为'静态资源'
- django
- 大而全 自带的功能非常的多 但是有时候会略显笨重
- 类似于'航空母舰'
-
- flask
- 小而精 自带的功能非常的少 但是第三方模块非常的多
- 类似于'游骑兵'
- # flask的第三方模块加到一起甚至比django还多 并且也越来越像django
- # flask由于过多的依赖于第三方模块 有时候也会受制于第三方模块
-
- tornado
- 异步非阻塞框架 速度极快 甚至可以用于充当游戏服务器
-
- # 还有一些占比较小 但是也很厉害的框架
- fastapi、sanic......
-
- """
- 框架的核心逻辑几乎是一致的 我们在学习的时候只需要先学会一种
- 之后就可以触类旁通 但是需要强调的是:千万不用同时学习!!!
- """
- django3.X:自带异步功能
- django2.X:默认不支持异步
- django1.X:默认不支持异步
- '''
- 学习基于django1.X版本即可原因: 老项目中使用频率最高、最广泛的版本!!!
- 与2.X功能几乎一致,后续会讲解两者区别之处
- 与3.X最主要的区别在于新增了一个异步的功能
- '''
- pip3 install django==1.11.11
- '''如果之前下载了其他版本不用管 自动替换!!!'''
启动如果报错,根据提示找到修改widgets.py文件第152行源码,删除最后的逗号即可
cmd窗口直接输入django-admin有一长串结果展示表明成功(需提前配置解释器环境变量)
- # 1.创建django项目
- django-admin startproject 项目名(如:mysite)
- # 2.启动django项目
- cd 项目名(如:mysite)
- python3 manage.py runserver IP:PORT
- '''IP:PORT可以不写 默认在本地8000端口起服务'''
- # 3.创建app应用
- python3 manage.py startapp 应用名(jason01)
django框架相当于是一所大学,应用相当于是大学里面的各个学院
大学相当于是个空壳子 负责提供环境
学院才是一个个真正具备特定功能的集合
eg:
使用django写一个淘宝,淘宝里面有很多功能模块
我们应该先创建一个空的django项目然后根据功能的不同创建不同的应用
django项目
应用名01(user) 用户相关业务
应用名02(order) 订单相关业务
应用名03(goods) 产品相关业务
应用名04(backend) 后台相关业务
-mysite文件夹名称
--mysite同名文件夹
----settings.py 项目配置文件
----urls.py 总路由层
--manage.py 项目入口文件
--db.sqlite3 运行项目后自动创建(django自带的小型数据库)
--应用文件夹 通过命令创建(可以创建任意个数)
----migrations文件夹 存储数据迁移记录
----admin.py django提供的后台管理
----apps.py 用于配置文件的应用注册(创建的应用都需要去配置文件中注册)
----models.py 模型层(与数据库相关)
----views.py 视图层(编写当前应用核心业务逻辑代码)
----tests.py 自带的测试文件