web框架
手写web框架
1.web框架可以看成是一个功能强大的socker服务端
先根据socket套接字编写一个简易的服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
sock, address = server.accept()
data = sock.recv(1024)
sock.send(b'HTTP/1.1 200 OK/r/n/r/n')
print(data.decode('utf8'))
2.根据不同请求对应响应
2.1socket代码
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
sock, address = server.accept()
data = sock.recv(1024)
sock.send(b'HTTP/1.1 200 OK/r/n/r/n')
target_url = data.decode('utf8').split(' ')[1]
if target_url == '/index':
sock.send(b'index view')
elif target_url == '/login':
sock.send(b'login view')
elif target_url == '/reg':
sock.send(b'reg view')
else:
sock.send(b'404 error')
3.代码缺陷
3.1socket代码重复编写、反复造轮子
3.2请求数据格式的处理复杂且重复
3.3不同网址后缀的匹配方式太简陋
基于wsgiref模块写框架
1.wsgiref内部封装了socket代码和对应请求数据的处理
from wsgiref.simple_server import make_server
def run(request, response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给客户端的数据
"""
print(request) # 自动将请求数据全部处理成字典k:v键值对形式
response('200 OK', []) # 固定代码
return [b'hello good bye']
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run) # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号调用
server.serve_forever() # 永久启动
'''
wsgiref模块解决了两个问题
1.socket代码重复编写、反复造轮子
2.请求数据格式的处理复杂且重复
'''
2.根据不同的网址后缀返回不同的内容(函数化)
'从大字典中查找出不同的网址后缀的键值对,不推荐使用多个if判断,对面条版代码可以封装成函数'
from wsgiref.simple_server import make_server
def index():
return 'index'
def login():
return 'login'
def register():
return 'register'
def error():
return '404 error'
urls = (('/index', index),
('/login', login),
('/register', register))
def run(request, response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给客户端的数据
"""
response('200 OK', []) # 固定代码
target_path = request.get('PATH_INFO')
func_name = None
for url_tuple in urls:
if url_tuple[0] == target_path:
func_name = url_tuple[1] # 存储匹配到的函数名
break # 匹配的函数名后立刻结束for循环
if func_name: # 判断func_name有没有匹配到函数名
res = func_name()
else:
res = error()
return [res.encode('utf8')]
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run) # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号调用
server.serve_forever() # 永久启动
代码封装优化
1.根据py文件中功能的不同划分到不同的py文件(模块化)
urls.py 对应关系
view.py 功能函数
start.py 启动文件
templates文件夹 存储html
2.view.py
def index():
return 'index'
def login():
return 'login'
def register():
return 'register'
def error():
return '404 error'
3.urls.py
from views import *
urls = (('/index', index),
('/login', login),
('/register', register))
4.start.py
from wsgiref.simple_server import make_server
from urls import urls
from views import *
def run(request, response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给客户端的数据
"""
response('200 OK', []) # 固定代码
target_path = request.get('PATH_INFO')
func_name = None
for url_tuple in urls:
if url_tuple[0] == target_path:
func_name = url_tuple[1] # 存储匹配到的函数名
break # 匹配的函数名后立刻结束for循环
if func_name: # 判断func_name有没有匹配到函数名
res = func_name()
else:
res = error()
return [res.encode('utf8')]
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run) # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号调用
server.serve_forever() # 永久启动
动静态网页
1.动态网页
页面上的数据不是全部写死的,有些是动态获取的(后端传入)
2.静态网页
页面上数据直接写死的,想要改变只能修改源码
3.实际需求
后端回去当前时间,让前端页面展示
3.1字符串替换
def get_time():
import time
ctime = time.strftime('%Y-%m-%d %H:%M:%S')
with open(r'templates/myhtml01.html', 'r', encoding='utf8')as f:
data = f.read()
data = data.replace('time', ctime) # 将html文件内数据替换成时间,在返回给浏览器
return data
3.2将字典数据传递给html页面并且想要在页面上操作字典数据
'在html页面上使用类似于后端的语法来操作数据类型>>>jinja2'
jinja2模板
1.jinja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型
def get_dict():
from jinja2 import Template
user_dict = {'name': 'barry', 'pwd': 123, 'age': 18}
with open(r'templates/myhtml01.html', 'r', encoding='utf8')as f:
data = f.read()
temp = Template(data)
res = temp.render(data=user_dict)
return res
'''
{'name': 'barry', 'pwd': 123, 'age': 18}
barry
123
18
'''
2.html文件语法
<body>
<h2>{{ data }}</h2>
<h2>{{ data['name'] }}</h2>
<h2>{{ data.get('pwd') }}</h2>
<h2>{{ data.age }}</h2>
</body>
前端、后端、数据库联动模板语法
1.views.py代码
def get_mysql():
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='321',
database='py02',
autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = 'select * from userinfo'
cursor.execute(sql)
user_data = cursor.fetchall()
with open(r'templates/myhtml01.html', 'r', encoding='utf8') as f:
data = f.read()
temp = Template(data)
res = temp.render(user_data=user_data)
return res
2.html文件语法
<body>
<div class="container">
<div class="row">
<h1 class="text-center">数据展示</h1>
<div class="col-md-6 col-md-offset-3">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{% for user in user_data %}
<tr>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
django
python主流web框架
1.django
大而全 自带功能非常多,当有事会略显笨重
缺陷:开发小项目时使用该框架有些笨重(大材小用)
2.flask
小而精 自身携带的功能非常的少,但是第三方模块非常多
缺陷:受限于第三方模块的开发
3.tornado框架
异步非zuse 该框架快到可以作为游戏服务器
缺点:上手难度是三者最高
4.fastapi框架、sanic框架、...
占比较小,但是也最近流行,可以了解一下
'''
框架内部逻辑几乎一致,我们在学习是只需要先学一种>>>django
'''
diango框架简介
1.版本
1.X:支持同步
2.X:支持同步
3.X:支持异步
2.启动注意事项
2.1计算机名称尽量不要有中文
2.2项目中所有的py文件名尽量不要用中文
2.3不同版本的python解释器配合不同版本的django,会有些报错
'仔细查找一下报错信息,里面会提示你是哪个朋友文件的代码出错,找到那行,把逗号删除即可'
widgets.py 152行
3.验证django是否下载成功
cmd终端输入:django-admin
diango基本操作命令
1.创建django项目
django-admin startproject 项目名
2.启动django项目
2.1先切换到项目目录下
cd 项目名
2.2执行启动目录
python38 manage.py runserver (ip:port)
3.访问django服务端
浏览器直接访问(http://127.0.0.1:8000/)
4.创建app应用
'''
django框架类似于一个空壳子,给你提供所需的资源
至于到底要写哪些功能,需要通过创建app来划分
django框架可以看成是一所大学,app相当于是大学里面的各个学院
'''
python38 manage.py startapp 应用名
5.pycharm操作
File>>>New Prozect...>>>Django
'在启动django项目的时候,一定要确保一个端口只有一个项目'
命令行与pycharm操作的区别
1.命令行不会自动创建templates文件夹
2.命令行不会在配置文件编写关于templates文件夹的配置
'DIRS': [os.path.join(BASE_DIR, 'templates')]
3.pycharm自动创建的第一个应用会自动注册到配置文件中
4.针对db.sqlite3文件不用在乎它有没有创建,只要运行了django就会自动出来
django目录结构
1.项目同名文件夹
__init__.py 很少用,主要做一些冷门配置
settings.py 项目配置文件
urls.py 对应关系(目前可以理解为:网址后缀与函数名的关系)
wsgi.py django服务,一般不用
mangae.py django入口文件(类似于启动文件)
templates文件夹 存储项目所需的html文件
2.应用名文件夹
migrations文件夹 orm相关(与数据库打交道的记录)
__init__.py 很少用,主要做一些冷门配置
admin.py django自带的后台管理
apps.py 创建应用之后用于用于的注册
models.py 存储与数据库表相关的类
tests.py 自带的测试文件
views.py 存储业务相关的逻辑代码(函数、类)
db.splite3 自带的小型数据库
3.主要文件
urls.py 路由层 对应关系
views.py 视图层 编写核心业务逻辑代码
templates.py 模板层 存储html文件的
models.py 模型层 与数据库相关
diango小白必会三板斧
1.HttpResponse
主要用于直接返回字符串类型的数据
2.render
主要用于返回html页面,并支持模板语法
3.redirect
主要用于页面重定向(自动跳转地址)
4.views.py
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
return HttpResponse('你好啊 django2.2.22版本')
def func(request):
user_dict = {'name': 'barry', 'pwd': 123}
return render(request, 'func.html', {'data': user_dict})
def login(request):
return redirect('https://www.baidu.com/')
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/283203.html