文章目录
手写Web框架(简易版)
什么是Web框架?
Web应用框架(Web application framework)是一种开发框架,用来支持动态网站、网络应用程序及网络服务的开发。其类型有基于请求的和基于组件的两种框架
web框架的应用作用:
Web应用框架有助于减轻网页开发时共通性活动的工作负荷
例如许多框架提供数据库访问接口、标准样板以及会话管理等,可提升代码的可再用性
web框架可以简单的理解为是基于互联网的web服务端>>>:socket服务端
补充知识:
两种请求方式:
-
GET:朝服务端索要数据(页面展示)
-
POST:朝客户端提交数据(eg:登录注册)
搭建简易版服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)
while True:
sock, adder = server.accept()
data = sock.recv(1024)
# print(data.decode('utf8'))
sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
curr_info = data.decode('utf8').split(' ')[1] # /index
if curr_info == '/index':
sock.send(b'/index')
elif curr_info == '/login':
sock.send(b'/login')
elif curr_info == '/reg':
sock.send(b'/reg')
else:
sock.send(b'404 error')
效果图:
但是这样也存在一些问题:
- 服务端起始代码过于重复
- 当数据众多的时候,针对请求格式的处理太过负责
- 针对不同后缀的处理方式太过于low(并发量问题)
基于以上前两个问题,我们可以通过wsgiref模块来解决
基于wsgiref模块写
WSGI(web服务器网关接口)是用Python编写web服务器软件和web应用程序之间的标准接口。有了这个标准的接口,就可以很容易地将支持WSGI的应用程序与许多不同的web服务器一起使用。
wsgiref内部封装了socket代码和对请求数据的处理
在书写之前需要我们先导入模块:
from wsgiref.simple_server import make_server
from wsgiref.simple_server import make_server
def index(request):
return 'index'
urls = [
('/index', index)
]
def run(request, response):
response('200 OK', [])
curr_path = request.get('PATH_INFO')
func_name = None
for func_info in urls:
if curr_path == func_info[0]:
func_name = func_info[1]
break
if func_name:
res = func_name(request)
else:
res = '404 not find'
return [res.encode('utf8')]
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run)
server.serve_forever()
实现根据不同的网址后缀返回不同的内容(函数化)
- 先从大字典中查找出记录网址后缀的键值对
- 不推荐使用连续的多个if判断
- 针对面条版的代码首先应该考虑封装成函数
我们对函数化版本再优化,由面条版优化成模块版
urls.py 存放对于关系
views.py 功能逻辑代码
start.py 启动代码
templates文件夹 存放html文件
动静态页面
理解:
动态页面
页面上的代码不是写死的,有一些是代码获取的(后端写入)
静态页面
页面上的代码是直接写死的,想要改变只能修改源码
举例说明:
需求:
后端代码回去当前时间 然后让前端页面展示(字符串替换)
def time(request):
import time
time_data = time.strftime('%Y-%m-%d %H:%M:%S')
with open('1.html', 'r', encoding='utf8') as f:
data = f.read()
res = data.replace('哈哈哈', time_data)
return res
需求2:
将字典数据传递给html页面并且想要在页面上操作字典数据
我们无法自己实现>>>:在html页面上使用类似于后端的语法操作数据
虽然我们不能做到,但是有模块可以做到(jinja2模块)
jinja2模块
基本使用
作用:
jinja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型
在编写前后端不分离项目的时候 可以使用该模块提供的模板语法简单快速的在html页面是使用类似于后端的代码语法操作数据
这是一个第三方模块,需要我们自己下载
pip3 install jinja2
功能实现:
HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1> {{ data }} </h1>
</body>
</html>
py文件代码
from jinja2 import Template
def get_info(request):
user_dict = {'name': 'jason', 'age': 18, 'pwd': 123}
with open('1.html', 'r', encoding='utf8') as f:
data = f.read()
temp = Template(data)
res = temp.render(data=user_dict) # 将字典传递给html页面 页面上通过data即可获取(data仅仅是一个变量名)
return res
模板语法
可以通过以下方式获取数据值
<h1>{{ data }}</h1>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('pwd') }}</h1>
<h1>{{ data.hobby }}</h1>
也可以支持for循环取值
{% for i in data %}
循环体代码
{% endfor %}
python主流web框架
-
django框架
优势:大而全 自身携带的功能非常的多 类似于航空母舰 缺陷:开发小项目的时候使用该框架有点笨重(大材小用)
-
flask框架
优势:小而精 自身携带的功能非常的少 类似于特种兵 主要依赖于第三方模块 flask的第三方模块加到一起甚至比django还多 并且也越来越像django 缺陷:受限于第三方模块的开发
-
tornado框架
优势:异步非阻塞 该框架快到可以作为游戏服务器 缺陷:上手难度是三者最高的
还有一些刚刚流行起来的以下小框架:fastapi框架、sanic框架、…
框架请求流程图
Django框架简介
版本问题
django3.X:默认支持异步功能
django2.X:默认不支持异步
django1.X:默认不支持异步
LTS代表的意思是官方会进行维护的版本
框架下载
pip3 install django==版本
'''如果之前下载了其他版本不用管 自动替换!!!'''
启动注意事项
- 计算机名称不要出现中文
- python解释器版本不同可能会出现启动报错
- 项目中所有的文件名称不要出现中文
- 多个项目文件尽量不要嵌套,做到一项一夹
注意:
不同解释器版本配和不同的django版本的时候,我们启动的时候还可能会出现报错,这时候我们需要找到该代码行,将其斜杠改为逗号
验证是否下载成功
cmd终端输入django-admin
如果终端有反应,则说明下载成功
Django基本操作
命令行操作
-
创建一个django项目
django-admin startproject 项目名称
-
启动一个django项目
1.先切换到项目目录下 cd 项目目录 2.执行启动目录 python3 manage.py runserver IP:端口号(也可不写,默认为8080)
-
访问django服务端
直接浏览器访问
-
创建一个app应用
python3 manage.py startapp 应用名
pycharm操作django
-
new project
选择django 填写应用即可
pycharm默认会自动帮你创建模板文件夹 并提供创建一个app的功能
-
创建更多的app
tools
run manage.py task 命令自动提示 -
启动项目
直接点击绿色箭头
还可以修改端口号 edit configurations
命令行与pycharm操作的区别
1.命令行不会自动创建templates文件夹
2.命令行不会在配置文件编写关于templates文件夹的配置
'DIRS': [os.path.join(BASE_DIR, 'templates')]
3.pycharm自动创建的第一个应用会自动注册到配置文件中
4.针对db.sqlite3文件不用去在乎它有没有创建 只要运行了django会自动出来
django目录结构
项目同名文件夹
__init__.py 很少用 主要做一些冷门配置
settings.py 项目配置文件
urls.py 对应关系(目前简单的理解:网址后缀跟函数名,eg:('/index',index))
wsgi.py django服务 基本不用
manage.py django入口文件
templates文件夹 存储项目所需的html文件
应用名文件夹(可以有多个)
migrations文件夹 orm相关(数据库打交道的记录)
__init__.py 很少用 主要做一些冷门配置
admin.py django自带的后台管理
apps.py 创建应用之后用于应用的注册
models.py 存储与数据库表相关的类
tests.py 自带的测试文件
views.py 存储业务相关的逻辑代码(函数、类)
db.sqlite3 自带的小型数据库
重要的文件:
-
urls
存储对应关系的(后缀名与函数名)
专业名词:路由层 -
views
存储业务相关逻辑(主要是函数,类)
专业名词:视图层 -
templates
存储项目所需的HTML文件
专业名词:模版层 -
models
存储与数据库表有关的类
专业名词:模型层
django小白必会三板斧
HttpResponse
主要用于直接返回字符串类型的数据
render
主要用于返回html页面 并且支持模板语法
redirect
主要用于页面重定向
重定向:就是我想去A页面,当我点击调转之后,调转到了B页面,不是我想要的页面
def index(request):
return HttpResponse('欢迎来到index页面') # 用于直接返回字符串
def login(request):
return redirect('https://baidu.com') # 重定向
今日作业
使用django展示MySQL数据到前端页面
from django.shortcuts import render,redirect, HttpResponse
# Create your views here.
import pymysql
def sql(request):
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
database='day51_django',
password='123',
charset='utf8',
autocommit=True
)
cou = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql1 = 'select * from django'
cou.execute(sql1)
data = cou.fetchall()
return render(request, 'sql.html', {'data': data}) # 用于返回HTML相关页面,并且支持模板语法