一 http协议简介,web框架基础,Django从入门到放弃,MVC和MTV模型
一、http协议简介
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
1.1、http协议特性
- 基于TCP/IP协议之上的应用协议
- 基于请求/响应模式
- 无状态保存
- http协议自身不对请求和响应之间的通信状态进行保存, HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理
- 每次有新的请求,都会有对应的新响应产生, 后续引用了cookie技术,就能够管理状态了
- 无连接
- 每次处理一个请求,处理完客户请求,并收到客户应答后,即断开连接
HTTP 协议体(重点)
请求头:
- 请求首行
- GET /index HTTP/1.1
- 请求头部(在django框架中,可以从META中取出来)
- key:value ----> \r\n分割
- 请求体(post请求发的数据) --> \r\n\r\n
- 往后台传数据的时候,有编码方式(urlencoded, form-data, json/text)
- 默认urlencoded --> name=xiong&age=100 --> 可以从GET/POST中取出
- form-data --> 上传文件, 数据在body体中 --> 也从POST中取出
- json --> 从POST中取不出来,只能从body中取出,然后反序列化
响应
- 响应首行 (用空格区分)
- HTTP/1.1 200 ok
- 响应头
- key:value
content-encoding: gzip
content-type: text/html; charset=utf-8
date: Fri, 22 Jan 2021 03:22:22 GMT
strict-transport-security: max-age=2592000; includeSubDomains; preload
vary: Accept-Encoding
- 响应体
- html/css/js代码
1.2、http请求协议与响应协议
1、发送请求、响应请求
2、请求协议
3、响应格式
4、响应状态码
1.3、自定义web框架
1.3.1、基于socket的web框架
#coding:utf-8
#
import socket
sock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 9070))
sock.listen()
while True:
sockd, addr = sock.accept()
data= sockd.recv(1024)
data = str(data, encoding='utf-8')
postion = data.split('\r\n')[0].split(" ")[1]
if "/index" == postion :
sockd.send(b'HTTP/1.1 200 OK \r\n\r\n hello world index')
else:
sockd.send(b'HTTP/1.1 200 OK \r\n\r\n hello world else')
sockd.close()
1.3.2、wsgiref模块
最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块。
基于wsgiref框架
# 路由与函数的映射关系
url.py
from view import index
urlpath = [
('/index', index)
]
view.py
def index():
return "hello index"
def error():
return "error 404"
#coding:utf-8
#
from wsgiref.simple_server import make_server
from view import error
from url import urlpath
def run(request, response):
response('200 OK', [('Content-type', "text/html")])
print(request) # html状态
func = None
for url in urlpath:
if request["PATH_INFO"] == url[0]:
func = url[1]
if func:
response = func()
else:
response = error()
return [response.encode('utf-8')]
if __name__ == '__main__':
# 创建socket连接
server = make_server('127.0.0.1', 9070, run)
# 一直监听
server.serve_forever()
1.4、python中的web框架
a: socker
b: 路由跟视图函数匹配关系
c: 模板渲染
django: a:使用了wsgiref, b:自己写的, c:自己写的
flask: a:使用了wsgiref, b:自己写的, c:用的jinja2
tornado: a:自己写的, b:自己写的, c:自己写的
二、django安装配置
2.1、安装及项目配置
-
安装:django版本说明
pip3 install django=1.11.9
- 通过pycharm下安装
-
配置项目
# 创建工程: django-admin startproject firstdjango 目录包含: firstdjango __init__.py asgi.py settings.py --> 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量 urls.py --> 总路由,请求地址跟视图函数映射信息 wgsi.py --> runserver命令就使用wsgiref模块做简单的web server,后面会看到renserver命令,所有与socket相关的内容都在这个文件里面了。 manage.py --> 项目入口,执行命令 # 创建项目: python manage.py startapp myapp 此时目录包含: 与工程 firstdjango同一个目录下, 与manage.py同级 myapp __init__.py admin.py --> 后台配置信息,无需关注 apps.py migrations/ --> 数据迁移的记录 models.py --> 数据库表模型 tests.py views.py --> 视图函数
-
启动项目
# > python manage.py runserver Starting development server at http://127.0.0.1:8000/ # 启动后默认端口是 8000
-
django创建app配置
一、 当工程执行完 python manage.py startapp myapps 二、 需要修改配置文件 settings.py中 INSTALLED_APPS = [ ... 'myapps.apps.MyappsConfig', # 添加配置文件 ]
2.2、登陆demo及静态文件
-
创建一个app:
python manage.py startapp myapps
-
修改配置文件
INSTALLED_APPS = [ # 引入myapps app
。。。
'myapps.apps.MyappsConfig',
]
STATIC_URL = '/static/' # 这里是html页面中引入时的名称,html引入的必须要与它保持一致
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static") # 这里可以导入多个目录,以逗号做为分割
]
- 项目/ulrs.py配置
from myapps.views import * # 先引入myapps.views页面
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', login), # 引入路由
]
- app下的views.py
from django.shortcuts import render, HttpResponse
import pymysql
# Create your views here.
def login(request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
# 如果是两个同样的username,那么使用getlist可以获取一个列表
usrename = request.POST.get("username")
pwd = request.POST.get("pwd")
# pymysql 1、连接, 2、获取游标、 3、查询语句 4、获取结果
py_con = pymysql.connect(host="192.168.9.10", user="django", password="django", database="mydjango")
py_cur = py_con.cursor(pymysql.cursors.DictCursor)
# 像多个引号的,遵循下外单内双的规则
py_cur.execute('select * from user_pwd where username="{0}" and password="{1}"'.format(usrename, pwd))
if py_cur.fetchone(): # 只获取一条
return HttpResponse("登陆成功")
return HttpResponse("<h1>用户名或密码错误</h1>")
- templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
<link rel="stylesheet" href="/static/css/bootstrap.css">
</head>
<body>
<h3>登陆</h3>
<div class="col-md-6 col-md-offset-3">
<form action="/login/" method="post">
{# 如果有两个相同的username, 那么在request.POST.get 中获取的一定是最后那一个 #}
<p>用户: <input type="text" class="form-control" name="username"></p>
<p>用户: <input type="text" class="form-control" name="username"></p>
<p>密码: <input type="password" class="form-control" name="pwd"></p>
<input type="submit" class="提交">
</form>
</div>
</body>
</html>
三、模型及生命周期
3.1、MVC与MTV模型
MVC
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器©和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
MTV
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
- M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
- T 代表模板 (Template):负责如何把页面展示给用户(html)。
- V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
3.2、django生命周期
新手三件套
render --> 返回页面
默认会去templates中查找 页面(*.html)
redirect --> 重定向
HttpResponse --> 页面响应, 而V的本质都是返回HttpResponse的对象
四、虚拟环境
通过virtualenv软件创建, 参考
# 一、安装:
>pip install virtualenv
# 二、创建虚拟环境:
>virtualenv env_django
created virtual environment CPython3.7.3.final.0-64 in 8588ms
# 三、激活虚拟环境
>dir
2021/01/11 11:15 <DIR> env_django
>cd env_django\Scripts> activate
# linux激活 :soruse env1/Script/activate
# 四、退出虚拟环境:
-deactivate