Django框架简介
web框架
前端 后端 数据库
客户端发生 >>> 服务端接收 >>> 处理 >>> 返回
'''
web框架:将前端、数据库整合到一起的基于互联网传输的python代码
web框架也可以简单的理解为是软件开发架构里面的'服务端
'''
# 遵循HTTP协议
四大特性、数据格式、响应状态码
# web框架的本质
所有的Web应用本质上就是一个socket服务端,而且用户的浏览器就是一个socket客户端

基于SOCKET写一个web应用
# 基于不同的后缀响应不同的内容
'''如何获取用户输入的url后缀>>>:HTTP请求数据
/favicon.ico直接忽略 不影响判断
利用字符串切割和索引取值获取相应数据'''
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8082)) # IP协议
server.listen(5) # 半链接池
while True:
sock, addr = server.accept()
data = sock.recv(1024)
# 将请求相关数据先转成字符串
data_str = data.decode('utf8') # 'GET /login HTTP/1.1\r\nHost: 127.0.0.1:8081\r\n......'
sock.send(b'HTTP1.1 200 OK\r\n\r\n')
# 然后去字符串中截取出我们需要的内容(按照空格切割字符串 获取第二个元素即可)
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.服务端起始代码过于重复 (服务端代码所有人都要重复写)
2.针对HTTP请求数据没有完善的处理方式
3.并发量问题
"""
基于Wsgiref模块
'''
做到后缀的不同返回不同的内容
拿到用户输入的url后缀 做判断
'''
# 1.利用模块搭建服务端
# 2.利用模块处理好的HTTP字典数据编写业务
查找用户url后缀对象的键值对数据
from wsgiref import simple_server
def run(request, response):
"""
:param request: 请求相关的数据
:param response: 响应相关的数据
:return: 返回给客户端的展示数据
"""
# print(request) # 字典类型的数据(模块自动处理HTTP请求数据 便于后续数据获取)
response('200 OK', []) # 固定编写 无需掌握
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']
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8080, run)
'''一致监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
server.serve_forever()


优化措施
封装处理
# 出现问题
1.如果网站很多 是不是就是以为的添加elif
2.每个分支下的功能根据业务逻辑的不同可能会比较复杂
# 处理
将匹配和功能封装成 元组和函数
根据功能的不同拆分成不同的py文件
#所有的代码全部放在一个py文件过于冗余 不便于后期管理维护
urls.py 路由与视图函数对应关系
views.py 视图函数(后端业务逻辑)
templates文件夹 专门用来存储html文件
static文件夹 存储项目所需的'静态文件'
路由:
路由就是url的后缀
视图函数:
函数处理的结果,一般都要经过浏览器,所以叫视图函数
'''按照功能的不同拆分之后 后续添加功能只需要在urls.py书写对应关系然后取views.py书写业务逻辑即可'''
html所学的css、js、第三方框架代码都是写完之后很少做改动的文件 所以可以统一存放在某个文件夹下
wsgiref.py 启动文件
from wsgiref.simple_server import make_server
# 导入对应关系文件
from urls import urls
# 导入业务逻辑文件
from views import *
def run(env,response):
"""
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return: 返回给浏览器的数据
"""
# print(env) #大字典 wsgiref模块帮你处理好http格式的数据 让你更好的操作
response('200 OK',[]) # 响应首行 响应头
# 从env中取 拿到当前用户输入的后缀
current_path = env.get('PATH_INFO')
# 定义一个变量 存储匹配到的函数名
func = None
for url in urls: # url (),()
# 判断用户输入后缀是否等于列表内的某个元组的第一个元素 访问后面的功能
if current_path == url[0]:
# 将url对应的函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束当前for循环
# 判断func是否有值
if func:
# 有值情况执行func()
res = func(env) # 将env传给函数
else:
res = error(env) # 将env传给函数
# 统一编码
return [res.encode('utf-8')]
if __name__ == '__main__':
# 接收mack_server 的返回值
server = make_server('127.0.0.1',8080,run)
"""
会实时监听127.0.0.1:8080地址 只要有客户端来了
都会交给run函数处理(加括号触发run函数的运行)
"""
server.serve_forever() # 启动服务端
urls.py 对应关系
# 导入业务逻辑文件
from views import *
# url与函数的对应关系
urls = [
('/index',index),
('/login',login),
('/xxx',xxx)
]
views.py 业务逻辑 (函数)
def index(env):
return 'index'
def login(env):
return 'login'
def error(env):
return '404 error'
def xxx(env):
# 打开templates文件夹内的html文件
with open(r'templates/myhtml.html', 'r',encoding='utf-8') as f:
return f.read()
动静态网页
# 静态网页
页面上的数据是直接写死的 万年不变
eg:上述项目中编写的 error.html func.html
# 动态网页
页面上的数据是通过代码动态获取的 实时可变
eg:
1.页面上展示当前时间(后端获取传递给前端界面)
2.页面上展示数据库数据(后端链接数据库查询数据再传递给页面)
展示当前时间案例
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('asdaksdjal',c_time)
return new_data
jinja2模块
# 第三方模块
pip3 install jinja2
# 功能介绍
在编写前后端不分离项目的时候 可以使用该模块提供的模板语法简单快速的在html页面是使用类似于后端的代码语法操作数据
# 模板语法
'将一个字典传递给html文件 并且可以在文件上方便快捷的操作字典数据'
temp_obj.render({'user':user_dict,'new_list':new_list})
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p>
{% for i in new_list %}
<span>元素:{{ i }}</span>
{% endfor %}
后端获取数据库中数据展示到前端页面
后端代码:
import pymysql
def get_user(env):
# 去数据库中获取数据 传递给html页面 借助于模板语法 发送给浏览器。
# 创建连接
conn = pymysql.connect( # 赋值给conn连接对象
host = '127.0.0.1', # 本地回环地址ip
port = 3306, # 端口
user = 'root', # 用户名
password = '123', # 密码
db='day01', # 连接数据库名称
charset = 'utf8', # 编码
autocommit = True # 自动提交
)
# 生成一个游标对象(相当于cmd打开MySQL中的 mysql>)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 让数据自动生成字典
# 定义sql语句
sql = 'select * from userinfo'
# 执行sql语句
affect_rows = cursor.execute(sql)
# [{},{},{}] 拿到的列表套字典
data_list = cursor.fetchall()
# 将获取到的数据传递给html文件
with open(r'templates/get_data.html','r',encoding='utf-8') as f:
data = f.read()
# 使用jinja2 就可以给html文件传值
tmp = Template(data)
# 给get_dict.html传递了一个值 页面上通过变量名user_list就能够拿到data_list
res = tmp.render(user_list=data_list)
return res
if __name__ == '__main__':
get_user(111)
前端代码:
<!--表格展示 列表套字典的数据 模板语法支持for循环-->
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center">用户数据</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<th>ID</th>
<th>username</th>
<th>password</th>
<th>hobby</th>
</tr>
</thead>
<tbody>
<!--[{},{},{},{}] 下面有一个列表套字典的用户数据 每拿一个字典 渲染一个tr-->
<!--模块语法操作-->
{% for user_dict in user_list %}
<tr>
<td>{{ user_dict.id}}</td>
<td>{{ user_dict.name}}</td>
<td>{{ user_dict.password}}</td>
<td>{{ user_dict.hobby}}</td>
{% endfor%}
</tr>
</tbody>
</table>
</div>
</div>
</div>

框架请求流程
urls.py
后缀与函数名对应关系
('/index',register)
后缀专业名词称之为'路由'
函数名专业名词称之为'视图函数'
urls.py专业名词称之为'路由层'
views.py
专门编写业务逻辑代码
可以是函数 也可以是类
函数专业名词称之为'视图函数'
类专业名词称之为'视图类'
views.py专业名词称之为'视图层'
templates文件夹
专门存储html文件
html文件专业名词称之为'模板文件'
templates文件夹专业名词称之为'模板层'
'''
wsgiref模块
1.请求来的时候解析http格式的数据 封装成大字典
2.响应走的时候给数据打包成符合http格式 再返回给浏览器
'''

python主流web框架
# django
特点:大而全 自带的功能特别特别特别的多 类似于航空母舰
不足之处:
有时候过于笨重
# flask
特点:小而精 自带的功能特别特别特别的少 类似于游骑兵
第三方的模块特别特别特别的多,如果将flask第三方的模块加起来甚至比django还多 并且也越来越像django
不足之处:
比较依赖于第三方的开发者,有时候也会受限于第三方模块
# tornado
特点:异步非阻塞 支持高并发
速度非常快 快到甚至可以开发游戏服务器
不足之处:
暂时你不会
'''
还有一些占比较小 但是也很厉害的框架
fastapi、sanic......
'''
django框架简介
# 版本问题
django3.X:默认支持异步功能
django2.X:默认不支持异步
django1.X:默认不支持异步
'''
我们学习的时候 可以基于django1.11.X版本 与2.X功能几乎一致
3.X仅仅是多了一个功能(并且该功能目前还不完善 半成品!!!)
'''
# 面试关于Django讲解
之前使用的是1.11 有些新项目逐步过渡到2.2 自己私下也研究过3.2

django下载
# 命令行安装
pip3 install django (最新版本)
pip3 install django==1.11.11
# pycharm下载django模块
如果之前下载了其他版本不用管 自动替换
'''如果报错 看看是不是timeout 如果是 那么只是网速波动
重新安装即可'''

验证是否下载成功
终端输入django-admin

命令行创建django项目
# 创建项目
django-admin startproject 项目名
django-admin startproject mysite
# 项目目录
'''
mysite文件夹
manage.py
mysite文件夹
__init__.py
settings.py
urls.py
wsgi.py
'''
启动django项目
# 切换到项目目录下
cd 项目名(mysite)
python3 manage.py runserver IP:PORT
# 可以指定端口 本地回环地址
python3 manage.py runserver 127.0.0.1:8080
python3 manage.py runserver 8080
django创建app应用
# 切换到项目路径创建应用
cd 项目名 :
# 命令行创建应用
python3 manage.py startapp 应用名
python3 manage.py startapp app01
'''命令行无法自动创建模板文件夹 需要自己执行命令创建''
app概念
# django是一款专注于开发app(应用)的web框架
django本身类似于是一个空壳子 真正的功能是由里面的各个应用决定
django框架相当于是一所大学 应用相当于是大学里面的各个学院
大学其实是个壳子 负责提供环境
学院才是一个个真正具备特定功能的集合
# 举例说明
使用django写一个淘宝
淘宝里面有很多功能模块
我们应该先创建一个空的django项目然后根据功能的不同创建不同的应用
django项目
app01(user) 用户模块
app02(order) 订单没款
app03(goods) 商品模块
app04(address) 收货地址
' 应用名应该做到见名知意'
pycharm操作django
1.new project
选择django 填写应用即可
'''pycharm默认会自动帮你创建模板文件夹 并提供创建一个app的功能'''
2.创建更多的app
tools
run manage.py task 命令自动提示
输入:startapp app01
3.启动项目
直接点击绿色箭头
还可以修改端口号 edit configurations

django主要文件介绍
mysite项目文件名
mysite同名文件夹
# settings.py 项目配置文件
# urls.py 路由层
# manage.py
django入口文件 很多命令都需要该文件支持
# db.sqlite3
django启动之后才会生成的文件 其实就是django自带的小型数据库
# templates文件夹 模板层
app01应用文件夹
# migrations文件夹 数据迁移记录
# admin.py django自带的后台管理
# apps.py 用于app的注册
# models.py 模型层 专门用于操作数据库
# views.py 视图层 主要用来写逻辑的
#tests.py 测试文件
