day02 简单web框架 django简单介绍
昨日内容复习
前端框架值bootstrap
1.引入方式
本地源文件 远程CDN(第一次用最好使用本地源文件)
2.bootstrap动态效果需要依赖于jQuery
3.布局容器
container
container-fluid
4.栅格系统
row
col-md-8
col-md-offset-2
5.css样式
表格
table table-hover table-strip
表单
form-control
按钮
btn btn-danger(颜色) btn-lg
6.组件
导航条
default
inverse
巨幕
面板
页码
图标
7.动态插件
模态框
socket服务端
server=socket.socket()# 创建连接对象
server.bind(('127.0.0.1',8080)) #绑定ip端口
server.listen(3) #监听
conn,addr=servr.accept() #获取链接信息和ip以及端口信息
conn.recv() #获取数据
conn.send()#发送数据
http协议
四大特征
1.基于请求响应
2.基于tcp/ip七层的应用层的协议
3.无状态
4.无连接或者叫短连接
数据结构
请求头
请求首行
换行
请求体(有的没有)
响应状态码
1xx 请求信息
2xx 请求成功
3xx 302 304 重定向
4xx 403 拒绝访问 权限不足 404 请求资源不存在
5xx 500 服务端内部错误
今日内容概要
主题:一定要懂框架编写的思路和流程(代码无需掌握)
* 纯手撸简易版本web框架
* 借助于wsgiref模块
* 动静态网页
* jinja2模板语法
* 前端、web框架、数据库三者结合
* python主流web框架
* django框架
今日内容详细
纯手撸简易版本web框架
import socket
server=socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(3)
while True:
conn,addr=server.accept()
data=conn.recv(1024)
conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
# print(data)
data=data.decode('utf-8')
tmp=data.split(' ')[1]
if tmp=='/index': #if elif 写太多
conn.send(b'hello index')
elif tmp=='/html':
with open('easy_html.html','rb')as f:
conn.send(f.read())
else:
conn.send(b'hello wow')
借助于wsgiref模块
from wsgiref.simple_server import make_server
def run(request,response):
'''
:param request: 请求相关的数据(都在这里)
:param response: 响应相关的数据
:return: 返回给前端浏览器的数据
'''
response('200 ok',[])
tmp=request.get('PATH_INFO')
if tmp == '/index':
return [b'from index']
elif tmp == '/login':
return [b'from login']
return [b'hello world']
if __name__ == '__main__':
#监听127.0.0.1:8080 一旦有请求 立刻将第三个参数加括号调用
server= make_server('127.0.0.1',8080,run)
#启动服务端
server.serve_forever()
优化代码
#简易版本 新增功能只需要新增函数 并且再加一组对应函数urls里 但是所有函数和对应关系都在一个py文件里显得有点混乱
from wsgiref.simple_server import make_server
def index():
return 'index wow'
def login():
return 'login wow'
def error():
return '404 !!!!!!!!!'
urls=[
('/index',index),
('/login',login)
]
def run(request,response):
'''
:param request: 请求相关的数据(都在这里)
:param response: 响应相关的数据
:return: 返回给前端浏览器的数据
'''
response('200 ok',[])
func=None
tmp=request.get('PATH_INFO')
for urls_tmp in urls:
if tmp== urls_tmp[0]: #取出来的是('/index',index)
func=urls_tmp[1]
break
if func:
res=func()
else:
res=error()
return [res.encode('utf-8')]
if __name__ == '__main__':
#监听127.0.0.1:8080 一旦有请求 立刻将第三个参数加括号调用
server= make_server('127.0.0.1',8080,run)
#启动服务端
server.serve_forever()
#在细分到文件 views(存放各种函数) urls(存放各种对应关系)
把函数拿出来放到views 对应关系拿出来放到urls
针对同一个py文件内部代码功能繁杂的情况 拆分多个py文件
views.py 专门用于存放核心业务逻辑
urls.py 专门用于存放路径对应关系
templates 专门用于存放html文件
动静态网页
动静态网页
动态网页
数据不是直接写死在html页面上的 而是动态获取(后端)
静态网页
数据是直接写死在页面上的
使用我们自己写的web框架 完成一个动态页面的返回
#主要是修改这个方法
from datetime import datetime
def timenow(request):
ctime=datetime.now().strftime('%Y-%m-%d-%X')
with open('templates/easy_html.html','rt',encoding='utf8')as f:
res=f.read()
res=res.replace('hahahahha我是亚索',ctime)
return res
jinja2模板语法
该模块提供了"模板语法"
支持后端给html页面传递数据并且支持后端语法
from jinja2 import Template
#函数里
def get_dict(request):
with open('templates/get_dict.html','rt',encoding='utf8')as f:
data=f.read()
res= Template(data) #Template
tmp=res.render({'user_dict':user})
return tmp
#网页里
<h1>{{user_dict}}</h1>
<h1>{{user_dict['username']}}</h1> #[]取值
<h1>{{user_dict.get('pwd')}}</h1> #get取值
<h1>{{user_dict.age}}</h1> #.函数名取值
#模板语法的for循环
<div>
{% for key in user_dict%}
<p>{{key}}</p>
{%endfor%}
</div>
前端、web框架、数据库三者结合
#创建数据库db7 和表user并添加数据
mysql> select * from user;
+----+-------+------+
| id | name | age |
+----+-------+------+
| 1 | zhang | 15 |
| 2 | as | 16 |
| 3 | uzi | 18 |
| 4 | ming | 20 |
| 5 | yasuo | 21 |
+----+-------+------+
#views里面
def get_user(request):
#1.先连接数据库 获取数据
conn=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123',
database='db7',
charset='utf8',
autocommit=True
)
cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
sql='select * from user'
cursor.execute(sql)
data=cursor.fetchall() #获取数据库的数据
#打开前端界面把数据传过去
with open('templates/get_user.html','rt',encoding='utf-8') as f:
html_data=f.read() #前端数据
#jinja2
res=Template(html_data) #把前端数据放在里面
tmp=res.render({'dict_list':data}) #后端数据
return tmp
#对应关系加一个
('/get_user',get_user)
#前端如下
<body>
<div class="container">
<div class="row">
<h1 class="text-center">用户数据表</h1>
<div class="col-md-8 col-md-offset-2"></div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{% for user_dict in dict_list %}
<tr >
<td>{{user_dict.id}}</td>
<td>{{user_dict.name}}</td>
<td>{{user_dict.age}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</body>
#结果图如下
python主流web框架
'''千万不要同时学习多个框架!!!'''
django框架
大而全 内部自带的组件特别特别多 类似于航空母舰
有时候可能会过于"笨重"
flask框架
小而精 内部几乎没有什么自带的组件 全部依赖于第三方模块 类似于游骑兵
如果将flask所有的第三方模块集合到一起甚至可以盖过django
有时候可能会出现第三方模块无法兼容的情况
tornado框架
异步非阻塞
"""
同步异步
同步:提交任务之后原地等待任务的返回结果 期间不做任何事
异步:提交任务之后不原地等待任务返回结果 有结果会通过回调机制反馈
阻塞非阻塞
阻塞:程序被剥夺了CPU执行权限
非阻塞:运行态 就绪态
"""
A:socket部分
B:路由匹配
C:模板语法
django
A:不是自己写的 用的wsgiref模块
B:自己写的
C:自己写的
flask
A:不是自己写的 werkzeug(依赖于wsgiref模块)
B:自己写的
C:不是自己写的 jinja2
Tornado
A,B,C全部都是自己写的
django框架
# 1.计算机名称里面最好不要含有中文
# 2.项目名和py文件名尽量也不要使用中文
django版本问题
django1.X
django2.X
django3.X
"""
3.X支持异步(但是目前写的不好)
1.X 2.X 3.X在使用上几乎没有太大差距
针对django版本使用1.11.11为学习对象
pip3 install django==1.11.11
"""
验证django是否下载完毕 #返回东西就行 前提是配置过python环境变量
django-admin
命令行
1.创建django项目
django-admin startproject 项目名
2.如何运行django项目
切到项目目录下
cd 项目名
python3 manage.py runserver ip加端口 #不跟默认
# 可能会报错 需要删除widgets.py152行逗号
3.创建app #ajango相当于一所大学 app相当于里面的各个学院 在django目录下执行
python3 manage.py startapp (app名字)
pycharm
"""
命令行创建不会自动创建templates文件夹 并且配置文件中也不会配置
需要自己创建文件夹并配置
os.path.join(BASE_DIR, 'templates')
"""