一、手搓web框架
1.socket服务端代码
2.HTTP协议 四大特性 数据格式 响应状态码!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3.根据网址后缀的不同请求不同的内容
4.请求方式
GET
朝服务端索要数据
POST
朝服务端提交数据
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)
# 因为是流式协议,可以把头先进行发送,之后再发送后面if种的东西
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')
5.从请求数据格式中筛选出用户输入的网址后缀
target_url = data.decode('utf8').split(' ')[1]
6.代码的缺陷
1.socket代码重复编写造轮子
2.针对请求数据格式的处理复杂且重复
3.针对不同网址后缀的匹配方式过于lowB
7.注意前面注释中的-因为是流式协议,可以把头先进行发送,之后再发送后面if种的东西
二、基于wsgiref模块撸
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 big baby']
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run) # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号调用
server.serve_forever() # 永久启动
1.wsgiref模块解决了两个问题
1.socket代码重复编写造轮子
2.针对请求数据格式的处理复杂且重复
三、基于wsgiref进行代码封装优化
from wsgiref.simple_server import make_server
def run(request, response):
"""
:param request: 请求数据
:param response: 响应数据
:return: 返回给客户端的数据
"""
response('200 OK, []')
target_path = request.get('PATH_INFO')
if target_path == '/index':
return [b'index']
elif target_path == '/login':
return [b'login']
else:
return [b'404']
if __name__ == '__main__':
# run的位置也可以是个对象
server = make_server('127.0.0.1', 8000, run)
server.serve_forever()
2.思考如何再次实现根据不同的网址后缀返回不同的内容(函数化)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
先从大字典中查找出记录网址后缀的键值对
1.不推荐使用连续的多个if判断
2.针对面条版的代码首先应该考虑封装成函数
利用多文件的函数封装来进行代码优化
具体文件在day22就不写出来了
四、动静态网页
动态网页
页面上的数据不是全部写死的 有些是动态获取(后端传入)
静态网页
页面上的数据直接写死的 要想改变只能修改源码
实际需求
后端代码回去当前时间 然后让前端页面展示
1.字符串替换
2.将字典数据传递给html页面并且想要在页面上操作字典数据
我们无法自己实现>>>:在html页面上使用类似于后端的语法操作数据
def get_time(request):
import time
current_time = time.strftime('%Y-%m-%d %H:%M:%S')
with open('templates/myhtml02.html', 'r', encoding='utf8') as f:
data = f.read()
data.replace('hahaha', data)
return data
五、jinjia2模块
jinja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型
pip3 install jinja2
from jinja2 import Template
def get_dict(request):
user_dict = {'name': 'jason', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
with open(r'templates/myhtml04.html','r',encoding='utf8') as f:
data = f.read()
temp = Template(data)
res = temp.render(data=user_dict) # 将字典传递给html页面 页面上通过data即可获取(data仅仅是一个变量名)
return res
**<!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>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('pwd') }}</h1>
<h1>{{ data.hobby }}</h1>
</body>
</html>**
这里Template的写法可能会有一点歧义,下面的那个会更加清晰一点
mac 版本的mysql安装以及添加环境变量
终端输入open .bash_profile
如果没有.bash_profile文件就自己创建一个
注意.bash_profile里面原来的东西别乱动
在文件中添加export PATH="$PATH":/usr/local/mysql/bin 保存
之后在终端输入source .bash_profile
现在重启终端依旧会消失
打开文件open .zshrc
在文件中输入source ~/.bash_profile
在命令端输入source .zshrc
就可以打开就使用mysql了
没有文件的情况下创建文件的指令 touch .文件名
六、前端、后端、数据库联动(render--提供的意思 execute--执行)
def get_mysql(request):
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='sy123456',
database='day55',
charset='utf8',
autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = 'select * from userinfo'
cursor.execute(sql)
user_data = cursor.fetchall()
with open('templates/myhtml04.html', 'r', encoding='utf8') as f:
data = f.read()
temp = Template(data)
res = temp.render(user_data=user_data)
return res
# 这样就可以直接利用user_data去调用数据库中的内容了
# cursor是最关键的单词
<!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://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text_canter">数据展示</h1>
<div class="col-md-6 col-offset-3">
<table>
<thead>
<tr>
<th>主键</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>
</html>
# {% for user in user_data %}的作用很大,能够让数据库在增删数据的同时网页也跟着变化!!!!!!!!!
# 注意这个代码的开始与结束,以及括号两边都需要加%,代码行只有一个{},数据获取行有两个{}
七、模板语法
<h1>{{ data }}</h1>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('pwd') }}</h1>
<h1>{{ data.hobby }}</h1>
{% for user in user_data %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
</tr>
{% endfor %}
八、python主流web框架
django框架
大而全 自身携带的功能非常的多 类似于航空母舰
缺陷:开发小项目的时候使用该框架有点笨重(大材小用)
flask框架
小而精 自身携带的功能非常的少 类似于特种兵 主要依赖于第三方模块
缺陷:受限于第三方模块的开发
tornado框架
异步非阻塞 该框架快到可以作为游戏服务器
缺陷:上手难度是三者最高的
fastapi框架、sanic框架、...
最近流行的 抽空可以看看
"""
框架虽然多 但是内部逻辑大差不差 我们重点学习一个即可>>>:django
如果你是小白切记不要同时学习上述框架
"""
九、django基本操作命令(这个面试很有可能会考)
命令行操作
1.创建django项目
django-admin startproject 项目名
2.启动django项目
1.先切换到项目目录下
cd 项目名
2.执行启动目录
python38 manage.py runserver ip:port
3.访问django服务端
浏览器直接访问
4.创建app应用
"""
django框架类似于是一个空壳子 给你提供所需的资源
至于到底要写哪些功能 需要通过创建app来划分
eg:django初始项目可以看成是一所大学
app就相当于是大学里面的各个学院
"""
python38 manage.py startapp 应用名
pycharm操作
鼠标点点点即可
"""
在启动django项目的时候 一定要确保一个端口只有一个项目!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""
1.先创建一个项目
django_admin stratproject mysite
2.切换到项目名文件夹下
cd mysite
3.利用文件夹下的文件启动django项目(manage.py是项目中的文件)
python3.9 manage.py runserver
4.访问django服务端
浏览器直接访问
5.先退出访问
crtl+c
6.创建app应用
python3.9 manage.py startapp app01
![image]()
要注意python的版本号得保持一致
![image]()
mac知识点补充说明
1.mac系统的默认文件目录为
Users/用户名/路径文件
2.mac版本的终端停止服务
也是crtl+c
十、命令行与pycharm操作的区别
1.命令行不会自动创建templates文件夹
2.命令行不会在配置文件编写关于templates文件夹的配置
'DIRS': [os.path.join(BASE_DIR, 'templates')]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 下面这句话需要自己加上去
'DIRS': [BASE_DIR,'templates'],
# 最标准的写法
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
3.pycharm自动创建的第一个应用会自动注册到配置文件中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01'
]
# 注意每当自己创建一个app就必须给他写进去!!!!!!!!!!!!!!!!!!!!!!
4.针对db.sqlite3文件不用去在乎它有没有创建 只要运行了django会自动出来
十一、django目录结构
django项目目录
项目同名文件夹
__init__.py 很少用 主要做一些冷门配置
settings.py 项目配置文件
urls.py 对应关系(目前简单的理解:网址后缀跟函数名)
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.py 路由层
views.py 视图层
templates 模板层
models.py 模型层
![image]()
十二、django小白必会三板斧
HttpResponse
主要用于直接返回字符串类型的数据
render
主要用于返回html页面 并且支持模板语法
redirect
主要用于页面重定向
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('func/', views.func),
path('login/', views.login)
]
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def index(request):
return HttpResponse('你好呀小宝贝')
def func(request):
user_dict = {'name': 'jason', 'pwd': 123}
return render(request, 'func.html', {'data': user_dict})
def login(request):
# return redirect('https://www.baidu.com')
return redirect('/index/')
最后提醒一下settings文件中加参数的时候类似于'DIRS': [os.path.join(BASE_DIR, 'templates')] 一定要加中括号!!!!!!!!!!