Django框架简介
web框架本质我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 这样我们就可以自己实现Web框架了。 半成品自定义web框架import socket
sk = socket.socket()
sk.bind(("127.0.0.1",80))
sk.listen()
while True:
conn,addr = sk.accept()
data = conn.recv(8096)
conn.send(b"OK")
conn.close()
可以说Web服务本质上都是在这十几行代码基础上扩展出来的。这段代码就是它们的祖宗。 用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定? 你这个网站是这个规定,他那个网站按照他那个规定,这互联网还能玩么? 所以,必须有一个统一的规则,让大家发送消息、接收消息的时候有个格式依据,不能随便写。 这个规则就是HTTP协议,以后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。 HTTP协议主要规定了客户端和服务器之间的通信格式,那HTTP协议是怎么规定消息格式的呢? 让我们首先打印下我们在服务端接收到的消息是什么。 import socket
sk = socket.socket()
sk.bind(("127.0.0.1",addr = sk.accept()
data = conn.recv(8096)
print(data) # 将浏览器发来的消息打印出来
conn.send(b"OK")
conn.close()
处女版自定义web框架import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind((‘127.0.0.1‘,8000))
sock.listen()
while True:
conn,addr = sock.accept()
data = conn.recv(8096)
# 给回复的消息加上响应状态行
conn.send(b"HTTP/1.1 200 OKrnrn")
conn.send(b"OK")
conn.close()
根据不同的路径返回不同的内容import socket
sk = socket.socket()
sk.bind(("127.0.0.1",8080)) # 绑定IP和端口
sk.listen() # 监听
while 1:
# 等待连接
conn,add = sk.accept()
data = conn.recv(8096) # 接收客户端发来的消息
# 从data中取到路径
data = str(data,encoding="utf8") # 把收到的字节类型的数据转换成字符串
# 按rn分割
data1 = data.split("rn")[0]
url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径
conn.send(b‘HTTP/1.1 200 OKrnrn‘) # 因为要遵循HTTP协议,所以回复的消息也要加状态行
# 根据不同的路径返回不同内容
if url == "/index/":
response = b"index"
elif url == "/home/":
response = b"home"
else:
response = b"404 not found!"
conn.send(response)
conn.close()
根据不同的路径返回不同的内容---函数版""" 根据URL中不同的路径返回不同的内容--函数版 """ import socket sk = socket.socket() sk.bind(("127.0.0.1",8080)) # 绑定IP和端口 sk.listen() # 监听 # 将返回不同的内容部分封装成函数 def index(url): s = "这是{}页面!".format(url) return bytes(s,encoding="utf8") def home(url): s = "这是{}页面!".format(url) return bytes(s,encoding="utf8") while 1: # 等待连接 conn,add = sk.accept() data = conn.recv(8096) # 接收客户端发来的消息 # 从data中取到路径 data = str(data,encoding="utf8") # 把收到的字节类型的数据转换成字符串 # 按rn分割 data1 = data.split("rn")[0] url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 conn.send(b‘HTTP/1.1 200 OKrnrn‘) # 因为要遵循HTTP协议,所以回复的消息也要加状态行 # 根据不同的路径返回不同内容,response是具体的响应体 if url == "/index/": response = index(url) elif url == "/home/": response = home(url) else: response = b"404 not found!" conn.send(response) conn.close() 根据不同的路径返回不同的内容---函数进阶版""" 根据URL中不同的路径返回不同的内容--函数进阶版 """ import socket sk = socket.socket() sk.bind(("127.0.0.1",encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/",index),("/home/",home),] while 1: # 等待连接 conn,encoding="utf8") # 把收到的字节类型的数据转换成字符串 # 按rn分割 data1 = data.split("rn")[0] url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 conn.send(b‘HTTP/1.1 200 OKrnrn‘) # 因为要遵循HTTP协议,所以回复的消息也要加状态行 # 根据不同的路径返回不同内容 func = None # 定义一个保存将要执行的函数名的变量 for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" # 返回具体的响应消息 conn.send(response) conn.close() 返回具体的HTML文件 """ 根据URL中不同的路径返回不同的内容--函数进阶版 返回独立的HTML页面 """ import socket sk = socket.socket() sk.bind(("127.0.0.1",8080)) # 绑定IP和端口 sk.listen() # 监听 # 将返回不同的内容部分封装成函数 def index(url): # 读取index.html页面的内容 with open("index.html","r",encoding="utf8") as f: s = f.read() # 返回字节数据 return bytes(s,encoding="utf8") def home(url): with open("home.html",encoding="utf8") as f: s = f.read() return bytes(s,encoding="utf8") # 把收到的字节类型的数据转换成字符串 # 按rn分割 data1 = data.split("rn")[0] url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 conn.send(b‘HTTP/1.1 200 OKrnrn‘) # 因为要遵循HTTP协议,所以回复的消息也要加状态行 # 根据不同的路径返回不同内容 func = None # 定义一个保存将要执行的函数名的变量 for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" # 返回具体的响应消息 conn.send(response) conn.close() 让网页动态起来""" 根据URL中不同的路径返回不同的内容--函数进阶版 返回HTML页面 让网页动态起来 """ import socket import time sk = socket.socket() sk.bind(("127.0.0.1",8080)) # 绑定IP和端口 sk.listen() # 监听 # 将返回不同的内容部分封装成函数 def index(url): with open("index.html",encoding="utf8") as f: s = f.read() now = str(time.time()) s = s.replace("@@[email?protected]@",now) # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号 return bytes(s,encoding="utf8") # 把收到的字节类型的数据转换成字符串 # 按rn分割 data1 = data.split("rn")[0] url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 conn.send(b‘HTTP/1.1 200 OKrnrn‘) # 因为要遵循HTTP协议,所以回复的消息也要加状态行 # 根据不同的路径返回不同内容 func = None # 定义一个保存将要执行的函数名的变量 for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" # 返回具体的响应消息 conn.send(response) conn.close() 服务器程序和应用程序对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。 服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。 应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。 ? 这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。 这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。 WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。 常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。 wsgiref我们利用wsgiref模块来替换我们自己写的web框架的socket server部分: """ 根据URL中不同的路径返回不同的内容--函数进阶版 返回HTML页面 让网页动态起来 wsgiref模块版 """ import time from wsgiref.simple_server import make_server # 将返回不同的内容部分封装成函数 def index(url): with open("index.html",encoding="utf8") as f: s = f.read() now = str(time.time()) s = s.replace("@@[email?protected]@",now) return bytes(s,] def run_server(environ,start_response): start_response(‘200 OK‘,[(‘Content-Type‘,‘text/html;charset=utf8‘),]) # 设置HTTP响应的状态码和头信息 url = environ[‘PATH_INFO‘] # 取到用户输入的url func = None for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" return [response,] if __name__ == ‘__main__‘: httpd = make_server(‘127.0.0.1‘,8090,run_server) print("我在8090等你哦...") httpd.serve_forever() jinja2上面的代码实现了一个简单的动态,我完全可以从数据库中查询数据,然后去替换我html中的对应内容,然后再发送给浏览器完成渲染。 这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具:? <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Title</title> </head> <body> <h1>姓名:{{name}}</h1> <h1>爱好:</h1> <ul> {% for hobby in hobby_list %} <li>{{hobby}}</li> {% endfor %} </ul> </body> </html> 使用jinja2渲染index2.html文件: from wsgiref.simple_server import make_server from jinja2 import Template def index(): with open("index2.html","r") as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({"name": "Alex","hobby_list": ["烫头","泡吧"]}) # 把数据填充到模板里面 return [bytes(ret,encoding="utf8"),] def home(): with open("home.html","rb") as f: data = f.read() return [data,] # 定义一个url和函数的对应关系 URL_LIST = [ ("/index/",]) # 设置HTTP响应的状态码和头信息 url = environ[‘PATH_INFO‘] # 取到用户输入的url func = None # 将要执行的函数 for i in URL_LIST: if i[0] == url: func = i[1] # 去之前定义好的url列表里找url应该执行的函数 break if func: # 如果能找到要执行的函数 return func() # 返回函数的执行结果 else: return [bytes("404没有该页面",] if __name__ == ‘__main__‘: httpd = make_server(‘‘,8000,run_server) print("Serving HTTP on port 8000...") httpd.serve_forever() 现在的数据是我们自己手写的,那可不可以从数据库中查询数据,来填充页面呢? 使用pymysql连接数据库: import pymysql def get_db(env): conn = pymysql.connect( host = ‘127.0.0.1‘,port = 3306,user = ‘root‘,password = ‘1‘,database = ‘day1‘,charset = ‘utf8‘,autocommit = True ) cursor = conn.cursor(pymysql.cursors.DictCursor) sql = "select * from userinfo" cursor.execute(sql) res = cursor.fetchall() with open(r‘templates/get_db.html‘,‘r‘,encoding=‘utf-8‘) as f: data = f.read() temp = Template(data) res = temp.render(user_list = res) return res Django版本问题Django下载 推荐下载1.11.11版本 命令行直接下载 pip3 install django==1.11.11 pycharm下载 验证是否下载成功 django-admin ? 创建django项目的方式: 方式1(命令行创建) 创建django项目 django-admin startproject 项目名 创建app应用 python3 manage.py startapp? app01 启动django项目 python3 manage.py runserver ps:用命令行创建django默认不会自动创建templates文件夹,需要手动创建(注意该文件夹路径是否添加配置文件中) ? 方式2(pycharm创建) FILE >>> new project? 选择第二个django? ?需要注意名字不能有中文,选择本地解释器,勾选后台管理 创建app pycharm命令行创建 Python3 manage.py startapp? app01 (*****) 创建的应用一定要在settings中注册? 才能生效? ?否则无法识别 django主要文件介绍 项目名文件 同名的项目文件夹 settings.py? django暴露给用户可配置的文件 urls.py? ?路由与视图函数对应关系 manage.py django入口文件 应用文件夹 migrations文件夹? ?数据库迁移记录 admin.py? ? django后台管理 app.py? 应用注册相关 models.py? orm模型类 test.py? 测试文件 views.py? 视图函数 django小白必会三板斧 HTTPResponse:返回字符串 render:返回html页面? 并且能够给该页面传值 redirect:重定向 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |