wsgiref 与 Django框架初识
前戏:
Web框架的本质
我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,这样我们就可以自己实现Web框架
软件开发架构:
c/s架构 客户端与服务端
b/s结构 浏览器与服务端
半成品自定义Web架构
import socket
server = socket.socket() # 不传参数默认TCP协议通信
# 绑定 IP PORT
server.bind(('127.0.0.1', 8080)) # 服务端:1.固定的ip+port,2.24小时不间断服务,3.支持高并发
# 半连接池
server.listen(5) # 降低效率,保证服务端硬件的安全性
while True:
conn, addr = server.accept() # 等待客户端连接
data = conn.recv(1024) # 接收客户端请求信息
conn.send(b'hello Django') # 向客户端响应信息,但响应失败,客户端无法接收,因为没有遵循HTTP协议
Web服务本质上都是这十几行代码基础上扩展出来的.
用户在浏览器输入网址:
浏览器发请求(get/post) <--> HTTP协议 <--> 服务端响应请求
HTTP协议规定了客户端与服务端消息的传世格式,那么我们就看看是怎样规定显式格式的,我们在服务端打印出接收到的信息是什么
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)
print(data) # 打印客户端请求数据
conn.send(b'hello Django')
# 打印出来的请求数据
'''
b'GET / HTTP/1.1\r\n
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
'
'''
我们发现收发的消息需要按照一定的格式来,这里就需要了解一下HTTP协议了
HTTP协议对收发消息的格式要求
每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。 HTTP响应的Header中有一个 `Content-Type`表明响应的内容格式。如 `text/html`表示HTML网页。
处女版自定义Web框架
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)
conn.send(b'HTTP/1.1 200 OK\r\n\r\nhello Django')
conn.colse()
以上就是web 框架的本质。
接下来就就是完善我们的自定义web框架
根据不同的路径返回不同的内容
如何让我们的Web服务根据用户请求的URL不同而返回不同的内容呢?
我们发现,用户输入不同的url在服务端接收的请求是不一样的,区别在与
b'GET /index HTTP/1.1\r\nHost: 127.0.0.1:8080\r\n.....
里面多了/index,也就是用户输入的url后缀,那么我们就可以通过切分拿到/index后缀,在进行判断返回相应的响应就可以
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)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # TCP 流式协议特性
data = data.decode('utf-8')
current_path = data.split('\r\n')[0].split(' ')[1] # 拿到url后缀
if current_path == '/index': # 判断后缀,响应响应的功能
conn.send(b'index')
elif current_path == '/text':
with open(r'1html.html', 'rb') as f:
conn.send(f.read())
else:
conn.send(b'hello Django')
conn.close()
wsgiref
from wsgiref.simple_server import make_server
# wsgiref 将socket封装好了
def run(env, response):
'''
env 是请求相关的数据
response 是响应相关的数据
'''
print(env) # 收到的是一个字典,里面的 键 PATN_INFO 对应的值就是客户端url的请求后缀
response('200 OK', [])
return [b'hello Django']
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run)
# 实时监测127.0.0.1:8080地址,一旦有客户端连接,会自动加括号调用run方法
server.serve_forever() # 启动服务端
根据不同的路径返回不同的内容--函数进阶版
from wsgiref.simple_server import make_server
# wsgiref 将socket封装好了
def index(env):
return 'index'
def login(env):
return 'login'
def errors(env):
return '404 error'
urls = [
('/index', index),
('/login', login),
]
def run(env, response):
response('200 OK', [])
current_path = env.get('PATH_INFO')# 拿到的是URL后缀
# 定义一个存储函数的标志位
func = None
for url in urls:
# 判断当前请求的url是否在元组内
if url[0] == current_path:
# 若在,赋值给func
func = url[1]
# 一旦匹配上就退出循环,节省资源
break
# 判断func是否有值
if func:
# 调用
res = func(env) # env是个大字典,里面含有信息,在后续的逻辑中可能还需要用到字典内的信息
else:
res = errors(env)
return [res.encode('utf-8')] # 将所有逻辑函数返回的字符串在此统一编码,发给客户端
if __name__ == '__main__':
server = make_server('127.0.0.1', 8080, run)
# 实时监测127.0.0.1:8080地址,一旦有客户端连接,会自动加括号调用run方法
server.serve_forever() # 启动服务端
基于wsgiref模块将代码拆分成urls.py路由文件,views.py视图文件和wsgiref通信文件三部分,后续加功能只需要在urls.py文件和view.py文件中加入对应功能即可
1.urls.py 路由与视图函数的对应关系
2.views.py 视图函数
让网页动态起来
静态网页:数据时写死的,万年不变
动态网页:如
1.后端实时获取当前时间'传递'给前端页面展示
2.后端从数据库获取数据'传递'给前端页面展示
ps : 传递即渲染
获取当前时间
from datetime import datetime
def get_time(env):
# 现在后端获取当前时间
current_time = datetime.now().strftime('%Y-%m-%d %X')
# 将获取的时间添加到HTML代码中的思路:
# 1.先在<body>内指定位置用一串字符占位($$time$$)
# 2.文件的形式读取HTML页面,对于计算机来说,html页面只是一串二进制数据
# 3.用 r 模式对出来的是一串字符串,利用字符串替换,将拿到的时间和站位的字符串替换即可
with open(r'templates/2get_time.html', 'r', encoding='utf-8') as f:
data = f.read()
data = data.replace('$$time$$', current_time)
return data
从数据库中查询数据
jinja2:
上面的代码实现了一个简单的动态,我完全可以从数据库中查询数据,然后去替换我html中的对应内容,然后再发送给浏览器完成渲染。
这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具: jinja2
from jinja2 import Template
import pymysql
def get_db(env):
conn = pymysql.connect(
host = '1270.0.1',
port = 3306,
user = 'root',
password = 'root',
database = 'db4',
charset = 'utf8',
autocommit = True,
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
sql = "select * form userinfo"
cursor.execute(sql)
data = cursor.fetchall()
with open(r'templates/4get_db.html', 'r', encoding='utf-8')as f:
data_user = f.read()
temp = Template(data_user)
res = temp.render(user_list = data)
return res
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2 class="text-center">用户数据展示</h2>
<table class="table table-hover table-bordered table-striped">
<thead>
<tr>
<th>id</th>
<th>username</th>
<th>password</th>
</tr>
</thead>
<tbody>
{%for user_dict in user_list%}
<tr>
<td>{{user_dict.id}}</td>
<td>{{user_dict.name}}</td>
<td>{{user_dict.password}}</td>
</tr>
{%endfor%}
</tbody>
</table>
</div>
</div>
模板渲染
后端生成的数据直接传递给前端页面使用(并且前端页面可以灵活的操作改数据) >>> 模板语法 模板渲染 模板语法需要依赖于第三方模块
pip install jinja2 模板语法 jinja2支持前端直接使用类似于python的语法操作数据,语法如下:
取值:
<p>{{ user_dic }}</p>
<p>{{ user_dic.name }}</p>
<p>{{ user_dic['password'] }}</p>
<p>{{ user_dic.get('name') }}</p>
for循环:
{% for user in user_dict %} <!--[{},{},{},{}]-->
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.password }}</td>
</tr>
{% endfor %}
正戏 Django
python三大主流web框架:
1. Django:大而全,自带了很多功能模块,类似于航空母舰 (缺点:有点笨重)
2. Flask:短小精悍,自带的功能模块特别少,大部分都是依赖于第三方模块(小而轻)
3. Tornado:异步非阻塞 主要用在处理高io 多路复用的情况 可以写游戏后端
a:socket
b:路由与视图函数
c:模板渲染
Django:
a用的别人的 wsgiref
b自己写的
c自己写的
Flask:
a用的别人的 werkzeug
b自己写的
c用的别人的 jinja2
Tornado:
a,b,c都是自己写的
使用Django注意事项(*****************************):
1.计算机的名称不能有中文
2.一个pycharm窗口就是一个项目,不要多个项目放在一个窗口里面
3.项目名不能起中文
一.djang下载 推荐下载1.11.11版本
命令行直接下载
pip3 install django==1.11.11
pycharm下载
验证是否下载成功:
django-admin
二.创建django项目的方式
1.命令行创建
创建django项目:
django-admin startproject 项目名
创建app应用(在项目名下):
django-admin startapp 应用名
python3 manage.py startapp 应用名
启动django项目
python3 manage.py runserver
ps:用命令行创建django默认不会自动创建templates文件夹
需要你手动自己创建(注意该文件夹路径是否被添加配置文件中)
Ctrl+c 停止运行
2.pycharm创建
FILE >>> new project 选择第二个django 需要注意名字不能有中文,选择本地的解释器,勾选后台管理
创建app
pycharm命令行创建
python3 manage.py startapp 应用名
Tools下面run manage task功能栏
startapp 应用名
启动点小绿色箭头
三.django各个文件的作用
1.应用名文件
migrations 数据库迁移记录相关数据
admin.py django后台管理相关
models.py 模型表相关
views.py 视图函数相关
apps.py 应用注册相关
texte.py 测试文件
views.py 视图函数
2.项目名文件
settings.py 配置文件
urls.py 路由与视图函数的映射关系
3.templates
项目用到的所有的html文件
4.manage.py
django入口文件
四.注意新创建的app需要在配置文件中注册才能生效(*******)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'应用名.apps.App01Config' # 可以用全称
'应用名' # 也可以简写
]
五.django小白必会三板斧
from django.shortcuts import render,HttpResponse,redirect
1.HttpResponse 返回字符串
return HttpResponse('字符串') # 例:
def index(request):
return HttpResponse('hello first django') # 返回字符串
2.render 返回HTML页面
return render() # 第一个参数request,第二个参数HTML,第三个参数字典 # 例:
def login(request):
user_dict = {'username':'haha'}
return render(request, '01 login.html', {'data':user_dict}) # 返回html页面
3.redirect 重定向
def home(request):
return redirect('/login/') # 重定向
wsgiref 与 Django框架初识的更多相关文章
- Django框架初识
一.安装: pip3 install django 注意pip加入环境变量,安装好以后记得把Django加入环境变量 安装完成后,会在python目录下多了两个文件:1个django文件,1个 ...
- python开发学习-day16(Django框架初识)
s12-20160507-day16 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- Django框架 之 Cookie和Session初识
Django框架 之 Cookie和Session初识 浏览目录 Cookie介绍 Django中的Cookie Session 一.Cookie介绍 1.Cookie产生的意义 众所周知,HTTP协 ...
- Django框架简介,wsgiref 与 jinja2 模块
目录 框架简介 wsgiref模块 jinja2 模块 框架简介 Django是一个web开发框架,用来开发web应用,本质就是, web框架+socket服务端 MVC框架和MTV框架 MVC,全名 ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- wsgiref模块、web框架、django框架简介
"""web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...
- 初识django框架
django框架 1.框架介绍 根据第一部分内容介绍,我们可以总结出一个web框架应该包含如下三部分:a.sockect服务.b.根据不同的url调用不同函数(包含逻辑).c.返回内容(模板渲染).常 ...
- web框架和Django框架的初识
1,web框架的原理 1.1>c/s架构和b/s架构 1>c/s客户端模式 2>B/S浏览器模式-----web开发(web开发开的是B/S架构) 1.2>web开发的本质 1 ...
- 初识Django框架——环境搭建前你需要了解的几点
Django是一个开放源代码的Web应用框架,由Python写成. 采用了MVC的框架模式,即模型M,视图V和控制器C. 它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是C ...
随机推荐
- LeetCode 442. 数组中重复的数据(Find All Duplicates in an Array) 17
442. 数组中重复的数据 442. Find All Duplicates in an Array 题目描述 Given an array of integers, 1 ≤ a[i] ≤ n (n ...
- Python中关于Lambda函数的使用总结
lambda表达式是一种匿名函数,对应python中的自定义函数def,是定义某个函数时比较高级的一种写法.作为python初学者,本文整理了lambda的一些基本用法和特点. lambda和def的 ...
- dotnet Core学习之旅(二):安装IDE
[重要:文中所有外链不能确保永久有效] >开发工具 高效的开发必然需要一个优秀的集成开发环境(IDE) 对于.NET Core 2.x可以使用包括但不限于以下IDE来进行开发. Visual S ...
- Spring Boot配置文件yml讲解--行内对象的配置方式
yml行内对象的配置方法,一般是采取 上面的缩进方式,我只想配置在一行怎么处?——
- O(1) gcd 板子
const int N = 2e5+10; const int M = 500; int cnt, p[N], _gcd[M][M]; int v[N][3],vis[N]; int gcd(int ...
- windows安装docker,快捷启动方式无法启动
1.在双击“Docker Quickstart Terminal”时弹出缺少快捷方式,截图如下 2.单机快捷方式查看属性,发现配置的git位置是有问题的 现在只需要把git的正确地址配置好就可以了 现 ...
- 怎样获取当前页面框架的数量(即iframe和frame的数量)
需要使用window.length, 或者window.frames.length; 如果页面中不包含frame和iframe元素, 则返回0; window.length === window.fr ...
- 第二次用map23333
度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如, ...
- sublime text3 关闭更新提醒
Preferences->settings 在Preferences.sublime-setting --User中 增加: "update_check":false,
- rabbitmd
一.前期准备 (1)条件:准备3台linux系统,确保能连到download.yunwei.edu (2)编写yum源下载脚本: vim yum-repo.sh wget -O /etc/yu ...