知识储备
正式学习Django之前,需要先对HTTP协议作一些了解
HTTP协议简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP协议的特性
2. 基于请求 / 响应模式
HTTP协议规定,请求从客户端发出,最后服务器端响应 该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应。
3. 无状态保存
HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议 自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个 级别,协议对于发送过的请求或响应都不做持久化处理。使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产 生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成 如此简单的。但是这里有一个问题,如果某些场景需要保存状态(如电商网站记录登录状态)怎么办呢?这就需要用到所谓的Cookie技术。
4. 无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP请求协议与响应协议
http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的响应协议。用于HTTP协议交互的信息被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身是由多行数据构成的字文本。
1. 请求协议
请求方式分为GET和POST两种,两者的区别:
1)数据放置的位置不同,GET的数据放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456。POST方法是把提交的数据放在HTTP包的请求体中;
2)安全性不同,由于GET方法的参数直接暴露在地址栏中,因而相对来说不如POST方法安全
3)数据大小不,GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制。
其实从本质来说,GET与POST并没有区别,因为都是基于TCP/IP协议,以上说的各种区别只是在应用层面人为规定的
参考链接2:https://zhuanlan.zhihu.com/p/38217343
2.响应协议
响应状态码是当客户端向服务器端发送请求时, 返回的请求结果。借助状态码,用户可以知道服务器端是正常理了请求,还是出现了问题 。状态码如200 OK,以3位数字和原因组成。响应状态码有以下5种
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协议开发的服务模块。
from wsgiref.simple_server import make_server def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'<h1>Hello, web!</h1>'] if __name__ == '__main__': httpd = make_server('', 8080, application) print('Serving HTTP on port 8080...') # 开始监听HTTP请求: httpd.serve_forever()
web框架
Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法。web框架已经实现了很多功能,开发人员使用框架提供的方法并且完成自己的业务逻辑,就能快速开发web应用了。
DIY一个web框架
1. 启动文件manage.py
from wsgiref.simple_server import make_server from urls import * def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')]) path = environ.get("PATH_INFO") # 获取url func = None # 防止出现变量未定义的错误 for item in urlpatterns:
# 如果path=url,就获取对应的函数 if path == item[0]: func = item[1]
# 获取到函数之后就退出循环 break if func:
# 如果函数存在,就执行函数并返回结果 ret = func(environ) else:
# 否则返回错误信息 ret = not_found(environ) return [ret] if __name__ == '__main__': httpd = make_server('', 8080, application) print('Serving HTTP on port 8080...') # 开始监听HTTP请求: httpd.serve_forever()
2. urls.py
from views import * urlpatterns = [ ("/login/", login), ]
3. views.py
def login(environ):
# 读取html文档内容并返回 with open("templates/login.html", "rb") as f: data = f.read() return data def not_found(environ): ret = b'<h1>404 not found.!!!</h1>' return ret
4. templates模板目录(该目录下的login.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="http://127.0.0.1:8080/login/" method="post"> <p>用户名:<input type="text" name="user"></p> <p>密码:<input type="password" name="pwd"></p> <input type="submit"> </form> </body> </html>
DIYWEB这个package就是一个web框架
Django简介
1. MVC与MTV模型
MVC
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同
- M 代表模型(Model) ,负责业务对象和数据库的关系映射(ORM)
- T 代表模板 (Template),负责如何把页面(html)展示给用户
- V 代表视图(View),负责业务逻辑,并在适当时候调用Model和Template
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
Django下载
官网下载:https://www.djangoproject.com/download/
pip下载:可以指定版本号,注意如果为Python3则要换成pip3 ...
pip install django==2.1.7
pycharm下载:File--Settings--Project--Project Interpreter--右上角+号--搜索Django
Django简单使用
1. 创建一个Django项目
命令行创建:注意执行此命令之前要切换到django-admin所在的目录
django-admin startproject mysite
pycharm创建:File--New Project--Django
2. 在项目目录下创建应用
python manage.py startapp app1
3. 注册应用
在settings.py里的INSTALLED_APPS列表中,添加注册app,注意如果在pycharm里创建的app不需要注册,pycharm已经帮我们注册好了
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app1.apps.App1Config', # app1是自己创建的app的名字 ]
app目录结构:
4.启动Django项目
在manage.py的同级目录下执行此命令,如果不传参数则默认ip为127.0.0.1,默认端口为8000
python manage.py runserver 127.0.0.1 8080
基于Django的一个简单示例
url控制器
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), ]
view视图函数
from django.shortcuts import render, HttpResponse, redirect def index(request): return render(request, "index.html") def login(request): if request.method == 'GET': return render(request, 'login.html') else: uname = request.POST.get('username') # 获取用户名 pwd = request.POST.get('password') # 获取密码 if uname == 'Robin' and pwd == '123': return redirect(request, 'index.html') return HttpResponse('密码错误!')
模板文件
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <h1>欢迎来到登录界面!</h1> <form action="" method="post"> {% csrf_token %} <label for="username">用户名</label> <input type="text" name="username" id="username"> <br> <label for="password">密码</label> <input type="password" name="password" id="password"> <br> <input type="submit"> </form> </body> </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>个人首页...</h1> </body> </html>