Django 00-socket、wsgi及初始django学习心得

HTTP基本原理
1.http简述:
http协议永远都是客户端发起请求,服务端回送请求。客户端和服务端本质上是一个socket客户端和服务端,http协议可以说是基于socket的再上层封装
2.http特性:
1)短链接
2)被动响应
3)无状态
Socket基本原理
Django 00-socket、wsgi及初始django学习心得
结合上图及下面的python代码,我们来一起学习一下socket的基本原理
 #!/usr/bin/env python
#_*_coding:utf-8_*_
#Author:Tiger At import socket #导入socket模块 def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建socket实例,AF_INET表示IPV4,SOCK_STREAM表示TCP连接
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #表示客户端失去连接后,服务端可以立即释放端口
sock.bind(('0.0.0.0', 8000)) #进行服务器的端口绑定
#开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
sock.listen(5) while True:
# 等待浏览器访问
conn, addr = sock.accept()
# 接收浏览器发送来的请求内容
data = conn.recv(1024)
print(data) # 给浏览器返回内容
conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n")
conn.send("电脑前的你长的真好看!".encode("utf-8")) # 关闭和浏览器创建的socket连接
conn.close() if __name__ == "__main__":
main()

socket_server

总结一下就是:创建socket实例->绑定IP地址及端口号(对外提供服务)->监听外来请求->接受请求->处理请求(数据交互)->关闭连接

#!/usr/bin/env python
#_*_coding:utf-8_*_
#Author:Tiger At
import socket
client = socket.socket() #创建socket实例 client.connect(("x.x.x.x",9999)) #与服务器建立连接
while True:
msg = input(">>>>>:").strip()
if len(msg) == 0:continue
client.send(msg.encode('utf-8')) #发送请求 data = client.recv(1024) #接收数据
print(data) client.close() #关闭连接

socket_client

总结一下就是:创建socket实例->主动发起连接->发送请求->接收结果->关闭连接

讲了这么多,这个到底与http有什么关系呢?上面我们提到过说:http的本质其实就是socket客户端和服务端,只是client变成了浏览器,而服务端只需要能处理浏览器的请求,并返回
相应结果就可以了。我这边摘出了"socket_server"中的部分代码,做详细解释:

# 给浏览器返回内容
conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n")   #表示:返回状态码为 200  Content-Type表示文本格式 charset表示字符编码。这些都是浏览器所需的信息不能缺少
conn.send("电脑前的你长的真好看!".encode("utf-8"))

#注上面要是直接写成 conn.send("电脑前的你长的真好看!"),只有再shell界面中能看到这个字符串了,浏览器是不会识别的

WSGI简介

WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app(应用程序)与web server(socket服务端)之间接口格式,实现web app与web server间的解耦。

通俗的说:当规范建立后,程序就不再重复编写web server(socket服务端),而是直接使用现成的实现WSGI的模块(例如:wsgiref、uwsgi、werkzeug),从而让程序员更加专注与业务代码

与其重复造*,不如直接用现成的。

Python的wsgiref是基于WSGI规范封装的模块,我们可以在这个模块基础上开发我们的web server

#!/usr/bin/env python
#_*_coding:utf-8_*_
#Author:Tiger At from wsgiref.simple_server import make_server #导入wsgiref模块 def run_server(environ, start_response):
"""
当有用户在浏览器*问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器
:param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
:param start_response: 响应相关
:return:
""" start_response('200 OK',[('Content-Type', 'text/html;charset=utf-8')])
return [bytes('<h1>我旁边的这个人长的真丑呀!!',encoding='utf-8'),] if __name__ == '__main__':
httpd = make_server('0.0.0.0',8001,run_server)
httpd.serve_forever()

wsgi_server

可以清晰的看到,使用了wsgiref模块后,我们直接使用make_server代替了服务器初始化的过程,使代码更加规范。我们再来看看下面的代码:

#!/usr/bin/env python
#_*_coding:utf-8_*_
#Author:Tiger At from wsgiref.simple_server import make_server def western():
return "欢迎来到欧美专区" def japan():
return "欢迎来到日本人专区" def routers():
"""负责把url与对应的方法关联起来"""
urlpatterns = (
('/western/',western),
('/japan/',japan),
) return urlpatterns def run_server(environ, start_response):
"""
当有用户在浏览器*问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器
:param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
:param start_response: 响应相关
:return:
"""
start_response('200 OK',[('Content-Type', 'text/html;charset=utf-8')])
url = environ.get("PATH_INFO")
urlpatterns = routers() func = None for item in urlpatterns:
if item[0] == url:
func = item[1]
break
if func:
return [bytes(func(),encoding="utf-8"),]
else:
return [bytes('404 not found.',encoding="utf-8"),] if __name__ == '__main__':
httpd = make_server('0.0.0.0',8001,run_server)
httpd.serve_forever()

对比之前的代码,我们可以看到我们做了相关路由选择功能urlpatterns,因此我们可以根据访问的url不通而显示不同的内容

小结

Web框架的本质

虽然自己写Web Server比较麻烦,但是我们从中也了解web框架的本质:

a.浏览器是socket客户端,网站是socket服务端

b.wsgi,是一个规范,wsgiref实现了这个规范并在其内部实现了socket服务端

c.根据 url 的不同执行不同函数,即:路由系统

d.函数,即:视图函数

e.图片、css、js文件 统一称为静态文件,需要读取内容直接返回给用户浏览器

Django初识

写在前面,既然web框架的本质如上面的小结所示,那django基本也是按照这个思路进行相应功能的封装和优化的,从而使用户更加关注于业务代码,让我们开始Django吧

开始一个Django项目:

1.使用 django-admin startproject mysite(此为项目名称,可根据具体需求定义)
├───mysite
│ │ manage.py #管理程序的文件,启动和结束等
│ │
│ └───mysite
│ settings.py #程序的配置文件
│ urls.py #程序的路由系统,即url和处理其函数的对应关系
│ wsgi.py #指定框架的wsgi
│ __init__.py
2.创建APP
python manage.py startapp app01(此为业务模块名称)
├───app01
│ │ admin.py #业务admin管理(数据库后台)
│ │ apps.py #业务配置(django把项目和app关联起来的一个文件)
│ │ models.py #数据库相关操作
│ │ tests.py #业务单元测试
│ │ views.py #业务代码(重要)
│ │ __init__.py
│ │
│ └───migrations #数据库相关
│ __init__.py 3.第一次django 请求
1)匹配路由,路由分发器查找用户请求得url对应关系
a.如果找到了业务函数就调用
b.找不到就报404
2)业务函数,执行业务逻辑
3)返回数据给浏览器 具体实现方式:
1) urls.py 编写路由
2)在views.py写一个业务函数
a.编写业务代码
b.通过HttpResponse方法返回数据给前端
3)python manage.py runserver 0.0.0.0:8000
注:127.0.0.1 环回测试地址,代表本机IP地址,访问127.0.0.1:80表示本机的80号端口,且仅表示内网访问
0.0.0.0 网络地址,0.0.0.0:80也表示本机IP地址,以外网的方式访问
这两种表示法用以对计算机端口进行权限设置
如果listen(0.0.0.0:XX),则这个可以被外部网络访问
而 listen(127.0.0.1:XX) 则这个端口只能被本机访问
4.模板初探
1)配置settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,"html")],
'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',
],
},
},
]
2)views.py 调用render方法
return render(response,"login.html") 声明:
1.本节内容用户自我学习与自我回顾使用
2.本文主要参考:https://www.cnblogs.com/alex3714/articles/8662706.html
https://www.cnblogs.com/alex3714/articles/5830365.html
进行梳理学习,详细内容可参阅如上URL。
3.希望可以与大家一起共同进步。
上一篇:Codeigniter使用HMVC(一)


下一篇:Inside Microsoft SQL Server 2008: T-SQL Querying 读书笔记之查询优化