Django入门
web框架
所有的web本质上就是一个socket服务端,用户的浏览器就是一个socket客户端
http协议规定了客户端与服务端之间的通信格式
一个http包含Header和Body两部门,其中Body是可选的
功能:
1.socket收发消息
2.根据不同的路径返回不同的结果
3.动态页面(字符串替换)
HTTP请求方法
get 获取
post 提交
head
put
delete
trace
options
connect
状态码
1xx 消息 请求已被服务器接收,继续处理 2xx 成功 请求已成功被服务器接收 理解 并接受 "200 OK" 3xx 重定向 需要后续操作才能完成这一请求 4xx 请求错误 请求含有此法错误或者无法被执行 "404 Not Found" 5xx 服务器错误 服务器在处理某个正确请求是发生错误
URL 统一资源定位符
将从网络获取信息的五个基本元素包括在一个简单的地址中:
传送协议 http/https 层级URL标记符号(为[//],固定不变) 访问资源需要的凭证信息(可省略) 服务器(通常为域名,有时为IP地址 通过域名DNS解析获得IP地址) 端口号(以数字方式表示,若为HTTP的默认值“:80”可省略) 路径 (以“/”字符区别路径中的每一个目录名称) 查询 (GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题) 片段 以“#”字符为起点
HTTP请求格式
需要注意的是: get请求方法的请求数据为空
HTTP响应格式
浏览器发送请求接受响应流程:
1.在地址栏输入地址,发送GET请求
2.服务端接受到请求,拿到URL路径,根据不同的路径执行不同的函数
3.服务端把结果封装成符合HTTP响应格式的内容,发送给浏览器
4.浏览器接受到响应,断开链接,浏览器渲染结果
自定义web框架
import socket sk = socket.socket() sk.bind(('127.0.0.1',8000)) sk.listen(5) while 1: conn,addr = sk.accept() data = conn.recv(1024) conn.send(b'HTTP/1.1 200 OK\r\n\r\n') #状态行 conn.send(b'ok') #响应正文 conn.close()
根据不同路径返回不同内容
import socket sk = socket.socket() sk.bind(('127.0.0.1',8000)) sk.listen(5) while 1: conn,addr = sk.accept() data = conn.recv(1024) data_str = data.decode('utf-8') # 将请求数据字节转换成字符串 data1 = data_str.split('\r\n')[0] # 按照\r\n分割,获取请求行:请求方法+空格+URL+空格+协议版本+回车符+换行符 url = data1.split()[1] # 以空格分割,获取URL conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 按照响应格式,先发送状态行 # 根据不同路径返回不同内容 if url == '/index/': response = b'index' elif url == '/home/': response = b'home' else: response = b'404 Not Found' conn.send(response) conn.close()
根据不同路径返回不同内容(函数版)
import socket sk = socket.socket() sk.bind(('127.0.0.1',8000)) sk.listen(5) # 将返回的不同内容封装成函数 def index(url): ret = f'{url}----index' return ret.encode('utf-8') def home(url): ret = f'{url}----home' return ret.encode('utf-8') # 将url和函数的对应关系写在列表里 lst = [ ('/index/',index), ('/home/',home), ] while 1: conn,addr = sk.accept() data = conn.recv(1024) data_str = data.decode('utf-8') # 将请求数据字节转换成字符串 data1 = data_str.split('\r\n')[0] # 按照\r\n分割,获取请求行:请求方法+空格+URL+空格+协议版本+回车符+换行符 url = data1.split()[1] # 以空格分割,获取URL conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 按照响应格式,发送状态行 # 循环列表 执行url对应的函数 for i in lst: #拿到每个元祖 if i[0] == url: response = i[1](url) #调用对应函数,return 返回字节形式 break else: response = b'404 Not Found' conn.send(response) conn.close()
根据不同路径返回html页面(动态html页面)
import socket import time sk = socket.socket() sk.bind(('127.0.0.1',8000)) sk.listen(5) # 将返回的不同html文件封装成函数 def index(url): with open('index.html','r',encoding='utf-8') as f: s = f.read() return s.encode('utf-8') def home(url): with open('home.html', 'r', encoding='utf-8') as f: s = f.read() return s.encode('utf-8') def timer(url): with open('time.html', 'r', encoding='utf-8') as f: s = f.read() ss = s.replace('@@time@@',time.strftime('%Y-%m-%d %H:%M:%S')) #使用字符串替换制作动态页面 return ss.encode('utf-8') # 将url和函数的对应关系写在列表里 lst = [ ('/index/',index), ('/home/',home), ('/time/',timer), ] while 1: conn,addr = sk.accept() data = conn.recv(1024) data_str = data.decode('utf-8') # 将请求数据字节转换成字符串 data1 = data_str.split('\r\n')[0] # 按照\r\n分割,获取请求行:请求方法+空格+URL+空格+协议版本+回车符+换行符 url = data1.split()[1] # 以空格分割,获取URL conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 按照响应格式,发送状态行 # 循环列表 执行url对应的函数 for i in lst: #拿到每个元祖 if i[0] == url: response = i[1](url) #调用对应函数,return 返回字节形式 break else: response = b'404 Not Found' conn.send(response) conn.close()
服务器程序和应用程序
服务器程序负责对socket服务端进行封装,并在请求到来时,对请求的各种数据进行整理.
应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。
这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。
WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。
from wsgiref.simple_server import make_server # 将返回不同的内容部分封装成函数 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", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8") def timer(url): import time with open("time.html", "r", encoding="utf8") as f: s = f.read() s = s.replace('@@time@@', time.strftime("%Y-%m-%d %H:%M:%S")) return bytes(s, encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/", index), ("/home/", home), ("/time/", timer), ] 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()
jinjia2 渲染
from wsgiref.simple_server import make_server from jinja2 import Template def index(url): # 读取HTML文件内容 with open("index2.html", "r", encoding="utf8") as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({'name': 'alex', 'hobby_list': ['抽烟', '喝酒', '烫头']}) # 把数据填充到模板中 return bytes(ret, encoding="utf8") def home(url): with open("home.html", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/", index), ("/home/", home), ] 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()
Django
创建Django项目
方式一: 命令行
切换到存放项目的目录下 django-admin startproject 项目名
方式二: pycharm
file ——》 new project ——》 django ——》 输入项目目录 ——》 选择解释器 ——》输入一个app名称 ——》创建
启动项目
方式一:命令行
切换到项目根目录下 manage.py
python manage.py runserver # 127.0.0.1:8000 python manage.py runserver 80 # 127.0.0.1:80 修改端口 python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80 修改ip和端口
方拾二: pycharm
点击三角是启动本项目
可以在下拉选项中修改ip和端口
# Django代码具体示例 在urls文件中
from django.shortcuts import HttpResponse,render # HttpResponse 内部传入一个字符串参数,返回给浏览器 # render 渲染 将数据填充进模板文件,最后把结果返回给浏览器(类似于jinja2) def index(request): '''业务逻辑''' # return HttpResponse('<h1>index</h1>') #可以识别标签 return render(request,'index.html') # 第一个参数为request,第二个参数为写好的html文件 def login(request): return render(request,'login.html') # URL地址和函数的对应关系 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/',index), url(r'^login/',login), ]