Django前戏
一、纯手撸web框架
版本①、超简易,只用了socket模块
# 只用了socket模块
# 做到传输html文件,以及自定义python的input输出到浏览器
import socket
server = socket.socket()
server.bind(("127.0.0.1",8080))
server.listen(5)
while True:
conn, addr = server.accept()
data = conn.recv(1024).decode("utf-8")
# print(data)
target_url = data.split(" ")[1]
print(target_url)
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
if target_url == "/index":
# cont = input("请输入要传给浏览器的内容").strip()
cont = "from /index"
cont_send = bytes(cont, encoding="utf-8")
conn.send(cont_send)
elif target_url == "/func":
with open("func.html","rb") as f:
data = f.read()
conn.send(data)
else:
conn.send(b"other")
-----------------------------------------------------------------------
存在的问题:
1、代码过于冗余,每个人创建服务端都重新写一份socket模块写的原始代码
每次都要绑定一次bind,监听端口等等操作
2、处理http数据繁杂
解决方法:
找一个其他模块,看能不能不用写这么复杂的代码,提高开发效率
# 下面尝试使用wsgiref模块
版本②、基于wsgiref模块撸web框架(python内置模块)
wsgi介绍
wsgi:
Python Web Server Gateway Interface
"""
是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。
自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。
"""
uwsgi
"""
uwsgi是一种通信协议,不过跟WSGI分属两种东西,该协议下速度比较快。
"""
wsgiref
wsgiref模块
"""
wsgiref则是官方给出的一个实现了WSGI标准用于演示用的简单Python内置库,
它实现了一个简单的WSGI Server和WSGI Application(在simple_server模块中)
要分为五个模块:simple_server, util, headers, handlers, validate。
"""
面条版代码1(耦合程度高,未整合)
from wsgiref.simple_server import make_server
def run(request,response):
"""
:param request: 跟请求相关的数据
:param response:跟相应相关的数据
:return: 返回值就是要返回给前端浏览器的数据
"""
response("200 OK",[]) # 为run方法return方法的空列表
print(request) # request为一个字典,将每个信息都装成了K:V键值对。
target_url = request.get("PATH_INFO") # PATH_INFO 为用户输入的网站后缀名
if target_url == "/index":
return [b"from /index"] # 返回给一个列表,里面是二进制的数据
elif target_url == "/func":
with open("func.html", "rb") as f:
data = f.read()
return [data]
return [b"hello world"] # 为response的空列表加值
if __name__ == '__main__':
# 监听127.0.0.1:8080,一旦有请求发来,立马将第三个参数app加括号调用
server = make_server("127.0.0.1",8080,app=run) # 第三个参数app是上面的run方法
# 启动服务端
server.serve_forever()
-----------------------------------------------------------------------
存在的问题:
1、用户输入的网站名以及返回的方法还需要一个个的添加
2、实际工作中,返回的文件代码会有很多很多行,每次修改光查哪里错了,都要找很久
解决方法:
做一个代码的整合,解耦合
# 将
面条版代码2(解耦合,整合)
from wsgiref.simple_server import make_server
def index(request):
return "index页面"
def login(request):
return "login页面"
def error(request):
return "error页面"
urls = [
("/index",index),
("/login",login),
]
def run(request,response):
"""
:param request: 跟请求相关的数据
:param response:跟相应相关的数据
:return: 返回值就是要返回给前端浏览器的数据
"""
response("200 OK",[])
print(request) # request为一个字典,将每个信息都装成了K:V键值对。
target_url = request.get("PATH_INFO") # PATH_INFO 为用户输入的网站后缀名
# 提前定义一个存储函数名的变量
func = None
for url_tuple in urls:
if target_url == url_tuple[0]:
func = url_tuple[1]
break
if func:
res = func(request)
else:
res = error(request)
return [res.encode("utf8")]
if __name__ == '__main__':
server = make_server("127.0.0.1",8080,app=run)
server.serve_forever()
-----------------------------------------------------------------------
存在的问题:
1、面条版的代码,只有一个py文件,功能不清晰
2、
解决方法:
将每个功能分别做成py文件,解耦合程度更高一些
py代码整合为多文件
"""
以后新增功能,只需要先在 "views文件" 内写一个函数,
然后在 "urls文件" 加一组对应关系即可
目录:
[项目名]--
|--templates # 文件夹,专门存放html文件
|--wsgi服务端代码启动.py
|--urls.py # 专门存放路径对应关系
|--views.py # 专门存放核心业务逻辑
"""
----------------------"wsgi服务端代码启动.py"----------------------
from wsgiref.simple_server import make_server
from urls import urls
from views import error
def run(request,response):
response("200 OK",[])
print(request)
target_url = request.get("PATH_INFO")
func = None
for url_tuple in urls:
if target_url == url_tuple[0]:
func = url_tuple[1]
break
if func:
res = func(request)
else:
res = error(request)
return [res.encode("utf8")]
if __name__ == '__main__':
server = make_server("127.0.0.1",8080,app=run)
server.serve_forever()
-----------------------------"urls.py"--------------------------
from views import *
urls = [
("/index",index),
("/login",login),
]
-----------------------------"views.py"--------------------------
def index(request):
return "index页面"
def login(request):
return "login页面"
def error(request):
return "error页面"
----------------------------------------------------------------
二、动静态网页
动静态网页
动态网页
数据不是直接写死在html页面上的 而是动态获取(后端)
静态网页
数据是直接写死在页面上的
使用我们自己写的web框架 完成一个动态页面的返回
三、jinja2模块
该模块提供了"模板语法"
支持后端给html页面传递数据并且支持后端语法
1、安装jinja2模块
pip3 install jinja2
2、在上面的views.py下
from jinja2 import Template
user = {"username": "yly", "pwd": 123, "hobby": ["play python","play ball"]}
def get_dict(request):
with open(r"Templates/get_dict.html", "r", encoding="utf8") as f:
data = f.read()
res = Template(data)
temp = res.render({"user_dict": user})
return temp
3、创建"Templates/get_dict.html" 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>{{user_dict}}</h1>
<h1>{{user_dict}}</h1>
<h1>{{user_dict['username']}}</h1>
<h1>{{user_dict.get('pwd')}}</h1>
<h1>{{user_dict.hobby}}</h1>
<div>
{% for key in user_dict%}
<p>{{ key }}</p>
{% endfor %}
</div>
</body>
</html>
4、打开web浏览器,输入"127.0.0.1:8080/get_dict",就显示字典内容
# 总结,jinja2的模板语法:
<h1>{{user_dict}}</h1>
<h1>{{user_dict['username']}}</h1>
<h1>{{user_dict.get('pwd')}}</h1>
<h1>{{user_dict.hobby}}</h1>
<div>
{% for key in user_dict%}
<p>{{ key }}</p>
{% endfor %}
</div>
四、前端、web框架、数据库三者结合
需求:
查找后端数据库的数据,通过代码传到前端html页面展示出来
准备:
准备mysql数据库表:
create database db_666;
use db_666;
create table user(id int primary key auto_increment,name varchar(32),pwd int);
insert into user(name,pwd) values('yly',111),('zpx',222),('aaa',333),('bbb',444),('ccc',555);
mysql> select * from user;
+----+------+------+
| id | name | pwd |
+----+------+------+
| 1 | yly | 111 |
| 2 | zpx | 222 |
| 3 | aaa | 333 |
| 4 | bbb | 444 |
| 5 | ccc | 555 |
+----+------+------+
5 rows in set (0.00 sec)
代码:
---------------------------------'urls.py'-------------------------------------
from views import *
urls = [
("/index",index),
("/login",login),
("/get_dict",get_dict),
("/get_user", get_user)
]
---------------------------------'views.py'-------------------------------------
import pymysql
def get_user(request):
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
passwd='123',
database='db_666',
charset='utf8',
autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from user;"
cursor.execute(sql)
data_list = cursor.fetchall()
with open(r"Templates/get_user.html", "r", encoding="utf8") as f:
data = f.read()
# jinja2模块
res = Template(data)
tmp = res.render({"data_list": data_list})
return tmp
html文件
----------------------------"Templates/get_user.html"---------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<a href="/index">进入index界面</a>
<a href="/get_dict">进入get_dict界面</a>
<div class="container">
<div class="row">
<h1 class="text-center">用户数据</h1>
<div class="col-md-8 col-md-offset-2">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>密码</th>
</tr>
</thead>
<tbody>
{% for user_dict in data_list %}
<tr>
<td>{{user_dict.id}}</td>
<td>{{user_dict.name}}</td>
<td>{{user_dict.pwd}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
运行
1、运行开始python代码
2、打开web,输入"127.0.0.1:8080/get_user"
五、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全部都是自己写的
知识储备:
fastapi框架
异步框架
六、Django框架正式介绍
1、安装及介绍
# 如何让你的计算机能够正常的启动Django项目
1、计算机名称不能有中文
2、一个pycharm窗口只开一个项目
3、项目里面的文件也尽量不要出现中文
4、python解释器尽量使用3.4~3.6之间的版本
# django版本问题
django1.X
django2.X
django3.X
# django安装
pip3 install django==1.11.11
如果已经安装了其他版本 无需自己卸载
直接重新装 会自动卸载安装新的
# 验证django是否下载完毕(命令自动安装放在pip下的scripts文件夹内)
django-admin
"""
3.X支持异步(但是目前写的不好)
1.X 2.X 3.X在使用上几乎没有太大差距
针对django版本我们以1.11.11为学习对象
"""
2、Django规划

3、django基本使用
----------------------------------"命令行"----------------------------------
1.创建django项目 # 运行这行代码,会在当前路径生成项目文件夹
django-admin startproject [项目名]
2.如何运行django项目
切到项目目录下
cd 项目名
python3 manage.py runserver
# 可能会报错 需要删除widgets.py152行逗号,python3.8解释器的错误
# 文件在Python3\lib\site-packages\django\contrib\admin\widgets.py
3.创建app
python3 manage.py startapp app名字
"""
命令行创建不会自动创建templates文件夹 并且 [项目]/settings.py 配置文件中也不会配置
需要自己创建文件夹并修改 "DIRS"
vim settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [], # 需要加入: os.path.join(BASE_DIR, 'templates')
# 这个参数是固定的,所以pycharm创建,会自动添加
'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',
],
},
},
]
"""
----------------------------------"pycharm启动"----------------------------------
1、new project 选择左侧第二个django即可
2、点击pycharm绿色小箭头即可启动
3、创建应用
pycharm使用django一些功能介绍
1、创建server以及配置启动ip及端口等等

2、pycharm便捷控制django,增加提示功能
例如:
startapp


4、什么是app应用
"""
django是一款专门用来开发app的web框架
django框架就类似于是一所大学
app就类似于大学里面各个学院
比如开发淘宝:
订单相关
用户相关
投诉相关
创建不同的app对应不同的功能
选课系统
学生功能
老师功能
一个app就是一个独立的功能模块
"""
django相当于一所大学(空壳子)
app相当于大学里面的各个学院(功能主题)
注意事项
# 如何让你的计算机能够正常的启动Django项目
1、计算机名称不能有中文
2、一个pycharm窗口只开一个项目
3、项目里面的文件也尽量不要出现中文
4、python解释器尽量使用3.4~3.6之间的版本
templates 放html文件
python小tips:
1、字符串与bytes类型的转换

str -> bytes
1、
bytes1 = "yly".encode(encoding="utf8")
2、
bytes2 = bytes("yly",encoding="utf8")
bytes -> str
1、
str1 = bytes1.decode(encoding="utf8")
2、
str2 = str(bytes2,encoding="utf8")
2、类、对象也可以加括号调用
类加括号是实例化一个对象
对象加括号是调用__call__方法
如果直接print一个对象,则是调用__str__方法,获得他的return返回值(必须是字符串)
3、html请求地址
remote_addr 发起请求的ip