python学习Day56
Day 56
今日内容概要
- 一.web框架
- 1.纯手工给搭建web框架
- 2.基于wsgiref模块搭建web框架
- 3.动静态网页
- 4.jinja2模板和语法
- python主流web框架介绍
- 二.django框架
- 1.django框架简介
- 2.django基本操作命令
- 3.cmd命令行与pycharm操作的区别
- 4.django目录结构
- 5.django必会三板斧
- (1)HttpResponse
- (2)render
- (3)redirect
今日内容详细
一.web框架
1.纯手工搭建web框架
web框架可以简单的理解为是基于互联网做数据交互的web服务端:socket服务端
1.socket服务端代码
2.HTTP协议
3.要求根据网址后缀的不同请求不同的内容
4.请求方式
GET:朝服务端索要数据(访问某页面)
PST:朝服务端提交数据(注册、登录等)
5.从请求数据格式中筛选出用户输入的网址后缀
target_url = data.decode('utf8').split(' ')[1]
————————————————————————————————————————————————
【初版:】
import socket
server=socket.socket()#括号内不写默认TCP协议
server.bind(('127.0.0.1',8080))#IP,端口
server.listen(5)#半连接池
while True:
sock,addr=server.accept()#等待客户端链接
data=sock.recv(1024)#收客户端发来的数据
sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
# print(data.decode('utf8'))#打印接收到的数据并解码
# 从字符串中截取出需要的内容
target_url=data.decode('utf8').split(' ')[1]
if target_url=='/index': #返回一个html页面
with open(r'myhtml01.html','rb')as f:
sock.send(f.read())
elif target_url == '/login':
sock.send(b'login view')
elif target_url == '/reg':
sock.send(b'reg view')
else:
sock.send(b'404 error')
————————————————————————————————————————————————
6.代码的缺陷
(1)socket代码重复编写
(2)针对请求数据格式的处理复杂且重复
(3)针对不同网址后缀的匹配方式较为没水平
2.基于wsgiref模块搭建web框架(很多python的web框架底层用的)
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)针对请求数据格式的处理复杂且重复
2.思考如何再次实现根据不同的网址后缀返回不同的内容(函数化)
先从大字典中查找出记录网址后缀的键值对
(1)不推荐使用连续多个if判断
(2)针对面条版的代码应该先考虑封装成函数
def index(request):
return 'index'
def login(request):
return 'login'
def error(request):
return '404 error'
def func(request):
with open(r'myhtml01.html','r',encoding='utf8')as f:
data=f.read()
return data
urls = (
('/index', index),
('/login', login),
('/func',func),
)
3.根据py文件中功能的不同划分到不同的py文件(模块化)
urls.py 对应关系
views.py 功能函数
start.py 启动文件
templates文件夹 存储html文件
【最终版: 把各个不同的功能划分不同的py文件】
_______________________________________________
start.py:
from wsgiref.simple_server import make_server
from urls import urls
from views import *
def run(request, response):
response('200 OK', []) # 固定代码 无需掌握
target_path=request.get('PATH_INFO')#发现输入的值都是键'PATH_INFO',点get可以获取值
func_name=None
for url_tuple in urls:#('/index',index) ('/login',login)
if url_tuple[0]==target_path:
func_name=url_tuple[1]#存储匹配到的函数名
break#当匹配到对应内容时结束for循环
#for循环结束后判断下func_name是否为None,如果为None则没有匹配到
if func_name:
res=func_name(request)
else:
res=error(request)
return [res.encode('utf8')]#统一最后解码处理
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run) # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号自动调用
server.serve_forever() # 永久启动
_______________________________________________
views.py:
def index(request):
return 'index'
def login(request):
return 'login'
def error(request):
return '404 error'
def func(request):
with open(r'myhtml01.html','r',encoding='utf8')as f:
data=f.read()
return data
_______________________________________________
urls.py:
from views import *
urls=(
('/index',index),
('/login',login),
('/func',func),
)
3.动静态网页
#动静态页面 不是看网页动不动!而是看数据来源是动态获取还是写死的
动态页面
页面上的数据不是全部写死的,有些是动态获取(后端传入)
静态页面
页面上的数据直接写死,要想改变只能修改代码
需求:
后端代码获取当前时间,然后让前端页面显示
1.字符串替换
def get_time(request):#把当前时间显示在页面中
import time#导入time模块
ctime=time.strftime('%Y-%m-%d %H:%M:%S')#获取当前时间
with open(r'templates/myhtml02.html','r',encoding='utf8')as f:
data=f.read()
#将时间嵌入到html文件数据内再返回给前端浏览器(用字符串替换)
data=data.replace('sssss',ctime)#把'sssss'替换成ctime当前时间
return data
2.将字典数据传递给html页面,且想在页面上操作字典数据
可以把字典数据传给html页面
但无法自己实现操作字典数据'需在html页面上使用类似于后端的语法操作数据'
4.jinja2模板
jinja2能够让我们在html文件内使用类似后端的语法来操作各种数据类型
'''
由于是第三方模块 需要先下载:
命令行终端中:pip 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
5.jinja2模板语法
html页面中不能随便写文本替换了:
<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 %}#加了这个才能在html中写for循环
6.python主流web框架
django框架(同步框架)
大而全 自身携带的功能非常多 类似于航空母舰
缺陷:开发小项目时用该框架有点笨重(大材小用)
flask框架(同步框架)
小而精 自身写的功能非常少 类似于特种兵 主要依赖于第三方模块
缺陷:受限于第三方模块的开发
tornado框架(异步框架)
异步非阻塞 该框架快到可以作为游戏服务器
缺陷:上手难度最高
fastapi框架、sanic框架...
最近流行的,一般很小的公司在用
'''
框架虽然多 但是内部逻辑都差不多 重点学django
小白切记不要同时学上述框架(易混淆)
'''
二.django框架
1.django框架简介
1.版本问题:
django1.X:同步框架 1.11
django2.X:同步框架 2.2
django3.X:异步框架 3.2
ps:哪个版本都可以(但是要用官方维护的版本LTS)
现阶段下载2.2版本用来学习
2.启动注意事项
(1)计算机名称不要有中文
(2)项目中所有的py文件名尽量不要有中文
(3)不同版本的python解释器配合不同版本的django会有一些报错
仔细查找报错信息 里面会提示是哪个py文件里的代码出错
找到那一行代码把最后面的逗号删除(widgets.py,line 152)
(4)一个pycharm窗口只允许有一个项目,不要做项目嵌套(会跑不起来)
3.验证django是否下载成功
cmd终端输入django-admin 有反应则下载成功
2.django基本操作命令
在启动django项目的时候 一定要确保一个端口只有一个项目
cmd命令行操作:
1.创建django项目
django-admin startproject 项目名
2.启动django项目
(1)先切换到项目目录下
cd 项目名
(2)执行启动目录
python38 manage.py runserver ip:port
#ip和端口不写默认就是本地127.0.0.1和8000端口
#8000端口是django默认端口号
'ctrl+c停止项目 (用完项目随手停止)'
3.访问django服务端
浏览器直接访问 地址:端口号
eg: 127.0.0.1:8000
4.创建app应用
python38 manage.py startapp 应用名
eg: python38 manage.py startapp app01
'''
django框架类似于是一个空壳子 给你提供所需的资源
至于到底要写哪些功能 需要通过创建app来划分
eg:django初始项目可以看成是一所学校
app相当于是学校里各个专业
'''
pycham操作:
1.启动django项目:运行即可(shift+F10)
#python3.8用jango2.2.22启动时会报错,找到报错位置把/换成英文逗号即可
2.修改项目端口号
3.cmd命令行与pycharm操作的区别
1.命令行不会自动创建templates文件夹
2.命令行不会在配置文件编写关于templates文件夹的配置
[pycharm]中templates配置其实不是标准写法,改为下面的兼容更强:
'DIRS': [os.path.join(BASE_DIR, 'templates')]
[命令行]创建的需自己找到templates文件,在文件内部添加
3.pycharm自动创建的第一个应用会自动注册到配置文件中
4.针对db.sqlite3文件不用在乎有没有创建,只要运行了django会自动创建
#总结:用pycharm创建更方便!!!!!
4.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 模板层 存储项目所需的html文件
models.py 模型层 存储与数据库表相关的类【重要】
5.django小白必会三板斧
#所有页面都是以这三种为基础扩展的!
1.HttpResponse 主要用于直接返回字符串类型的数据
【urls.py:】
from app01 import views
urlpatterns = [
path('index/', views.index),
]
【views.py:】
from django.shortcuts import render,HttpResponse,redirect
def index(request):
return HttpResponse('我是django2.22版本')
———————————————————————————————————————————————————
2.render 主要用于返回html页面 并且支持模板语法
【urls.py:】
from app01 import views
urlpatterns = [
path('func/', views.func),
]
【views.py:】
from django.shortcuts import render,HttpResponse,redirect
def func(request):
user_dict={'name':'jason','pwd':'123'}
return render(request,'func.html',{'data':user_dict})
【html:】
<body>
<h1>哈哈哈</h1>
<h1>{{ data }}</h1>
<h1>{{ data.name }}</h1>
<h1>{{ data.pwd }}</h1>
</body>
———————————————————————————————————————————————————
3.redirect 主要用于页面重定向(想访问a页面但是访问了b页面)
【urls.py:】
from app01 import views
urlpatterns = [
path('login/', views.login),
]
【views.py:】
from django.shortcuts import render,HttpResponse,redirect
def login(request):
return redirect('https://www.baidu.com/')
———————————————————————————————————————————————————
作业
1.整理今日内容及博客
2.重点理解web框架推导流程
3.顺利安装django并启动使用(使用django展示MySQL数据到前端页面)