一 HTTP相关概念
http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的响应协议。用于HTTP协议交互的信息被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身是由多行数据构成的字文本。
1.1 HTTP请求协议
请求方式: get与post请求
- GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的请求体中.
- GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制。
补充内容:对URL的认识
URL是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。
URL的组成部分(如:http://www.luffycity.com/home):
a、协议部分:在Internet中可以使用多种协议,如HTTP,FTP等等。上面的例子中“http”就是在声明协议,在"http"后面的“//”为分隔符。
b、域名部分:上面的例子URL的域名部分为“www.luffycity.com”。一个URL中,也可以使用IP地址作为域名使用(域名通过dns解析,最终访问的还是IP地址)。
c、端口部分:紧跟域名后面的就是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口(80)。
d、路径部分:以“/”字符区别路径中的每一个目录名称(如:http://www.luffycity.com/home,中的home就是路径名称)。
e、文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分(如:https://hcdn1.luffycity.com/static/frontend/index/Luffy-study-logo.png)。本例中的文件名是“Luffy-study-logo.png”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名。
f、锚部分:从“#”开始到最后,都是锚部分。锚部分也不是一个URL必须的部分。
g、参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
1.2 HTTP相应协议
1.3 响应状态码
状态码的职 是当客户端向服务器端发送请求时, 返回的请求结果。借助状态码,用户可以知道服务器端是正常理了请求,还是出现了问题 。状态码如200 OK,以3位数字和原因组成。响应状态码有以下5种(详见下图)。
1.4 WSGIRE模块
最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块。
1.5 web框架
Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法。web框架已经实现了很多功能,开发人员使用框架提供的方法并且完成自己的业务逻辑,就能快速开发web应用了。
浏览器和服务器之间是基于HTTP协议进行通信的。也可以说web框架就是在以上十几行代码基础张扩展出来的,有很多简单方便使用的方法,大大提高了开发的效率。
二 Django简介
2.1 MVC与MTV模型
MVC模型
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(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的响应模式如下所示:
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
2.2 Django下载与基本命令
2.2.1 安装
[root@node10 html]# pip3 install django==2.1.7
2.2.2 创建一个django的项目
[root@node10 html]# mkdir /django
[root@node10 html]# cd /django
[root@node10 django]# django-admin startproject mysite
[root@node10 django]# ll
drwxr-xr-x 3 root root 37 Apr 1 06:09 mysite #项目根目录
[root@node10 mysite]# cd mysite/
[root@node10 mysite]# ll
-rwxr-xr-x 1 root root 626 Apr 1 06:09 manage.py #管理相关
drwxr-xr-x 2 root root 89 Apr 1 06:09 mysite #项目名称
[root@node10 mysite]# cd mysite/
[root@node10 mysite]# ll
-rw-r--r-- 1 root root 389 Apr 1 06:09 asgi.py
-rw-r--r-- 1 root root 0 Apr 1 06:09 __init__.py
-rw-r--r-- 1 root root 3088 Apr 1 06:09 settings.py #配置文件
-rw-r--r-- 1 root root 748 Apr 1 06:09 urls.py #路由相关
-rw-r--r-- 1 root root 389 Apr 1 06:09 wsgi.py
2.2.3 创建templates
[root@node10 mysite]# pwd
/django/mysite
[root@node10 mysite]# mkdir templates
修改setting
[root@node10 mysite]# pwd
/django/mysite/mysite
修改
[root@node10 mysite]# vim settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,"templates")],
'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.2.4 在mysite下创建app应用
[root@node10 mysite]# python3 manage.py startapp app01
2.2.5 sqlite的版本太低需要升级
下载sqlite源码包安装:
[root@node10 src]# wget http://www.sqlite.org/2019/sqlite-autoconf-3280000.tar.gz
[root@node10 src]# tar zxvf sqlite-autoconf-3280000.tar.gz -C /usr/src/
[root@node10 src]# cd /usr/src/sqlite-autoconf-3280000/
[root@node10 sqlite-autoconf-3280000]#
[root@node10 sqlite-autoconf-3280000]# ./configure --prefix=/usr/local/sqlite
[root@node10 sqlite-autoconf-3280000]# make && make install
[root@node10 sqlite-autoconf-3280000]# mv /usr/bin/sqlite3 /usr/bin/sqlite3_old
[root@node10 sqlite-autoconf-3280000]# cd /usr/local/sqlite/bin/
[root@node10 bin]# ln -s /usr/local/sqlite/bin /usr/bin/sqlite3
[root@node10 bin]# vim /etc/profile
export LD_LIBRARY_PATH="/usr/local/sqlite/lib"
[root@node10 bin]# source /etc/profile
[root@node10 bin]# sqlite3 --version
3.28.0 2019-04-16 19:49:53 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50
[root@node10 bin]# cd /django/mysite/
[root@node10 mysite]# python3 manage.py startapp app01
[root@node10 mysite]# ll
drwxr-xr-x 3 root root 123 Apr 1 08:08 app01 #APP应用名称
-rwxr-xr-x 1 root root 626 Apr 1 07:34 manage.py
drwxr-xr-x 3 root root 108 Apr 1 07:35 mysite
drwxr-xr-x 2 root root 6 Apr 1 07:35 templates
setting.py注册app
[root@node10 mysite]# vi mysite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]
[root@node10 mysite]# ll app01/
-rw-r--r-- 1 root root 63 Apr 1 08:08 admin.py #admin后台管理相关
-rw-r--r-- 1 root root 85 Apr 1 08:08 apps.py #app的相关配置
-rw-r--r-- 1 root root 0 Apr 1 08:08 __init__.py
drwxr-xr-x 2 root root 25 Apr 1 08:08 migrations #数据迁移记录文件
-rw-r--r-- 1 root root 57 Apr 1 08:08 models.py #模型类文件
-rw-r--r-- 1 root root 60 Apr 1 08:08 tests.py #测试文件
-rw-r--r-- 1 root root 63 Apr 1 08:08 views.py #视图文件
2.2.6 启动django项目
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:8888 # 0.0.0.0:8888# 注意:要在manage.py同级目录执行命令
[root@node10 mysite]# python3 manage.py runserver 192.168.132.140:8888
Watching for file changes with StatReloader
Performing system checks... System check identified no issues (0 silenced). You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them. April 01, 2020 - 12:54:12
Django version 3.0.5, using settings 'mysite.settings'
Starting development server at http://192.168.132.140:8888/
访问
修改
[root@node10 mysite]# vi mysite/settings.py
ALLOWED_HOSTS = ["*"]
[root@node10 mysite]# python3 manage.py runserver 192.168.132.140:8888
访问
三 一个简单的登录案例
3.1 配置url.py
[root@node10 ~]# cd /django/mysite/mysite/
[root@node10 mysite]# vim urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
]
如果在这里不写返回
[root@node10 mysite]# vim ../app01/views.py
from django.shortcuts import render # Create your views here. def login(request):
print(request.method)
访问http://192.168.132.140:8888/
使用http://192.168.132.140:8888/login/访问
添加响应后
[root@node10 mysite]# cat ../app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def login(request):
print(request.method)
return HttpResponse("OK")
访问显示
查看调试
GET #得到get请求
[01/Apr/2020 13:55:48] "GET /login/ HTTP/1.1" 200 2
传回一个html文档
[root@node10 mysite]# vim ../app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def login(request):
print(request.method)
# return HttpResponse("OK")
return render(request,"login.html")
3.2 创建login.html
[root@node10 mysite]# vim ../templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</script>
</head>
<body>
<h3>用户登录</h3>
<form action="" method="post">
<p>用户名:<input type="text" name="user"></p>
<p>密 码:<input type="password" name="pwd"></p>
<input type="submit">
</form>
<script>
</script>
</body>
</html>
访问http://192.168.132.140:8888/login,得到登录页面
3.3 添加登录逻辑
添加view逻辑,当提交正确是,显示登陆成功,当提交错误时,再次返回登陆页面
[root@node10 mysite]# vi ../app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def login(request):
print(request.method)
if request.method == "GET":
return render(request,"login.html")
else:
#获取login.html获取到的user和pwd,这两个都是key
user = request.POST.get("user")
pwd = request.POST.get("pwd")
print(user,pwd)
if user == "darren" and pwd == "123456":
return HttpResponse("登录成功")
else:
return render(request,"login.html")
设置setting.py
[root@node10 mysite]# vi settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware', #如果不注释,会有403错误
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
3.4 登录验证
访问http://192.168.132.140:8888/login,得到登录页面,并填入非设定及错误用户名或者密码
点击提交,又返回到登陆页面
查看调试日志,已经得到用户名密码
POST
ning 123456
[01/Apr/2020 14:29:50] "POST /login/ HTTP/1.1" 200 345
输入正确的用户名密码
点击提交,返回登录成功
调试结果
POST
darren 123456
[01/Apr/2020 14:31:36] "POST /login/ HTTP/1.1" 200 12
结束