1、web应用

Web应用程序是一种可以通过web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序一般独立运行。而B/S就是浏览器端/服务器端应用程序,这类应用程序一般借助谷歌,火狐等浏览器来运行。WEB应用程序一般是B/S模式。Web应用程序首先是“应用程序”,和用标准的程序语言,如java,python等编写出来的程序没有什么本质上的不同。在网络编程的意义下,浏览器是一个socket客户端,服务器是一个socket服务端。

如下代码是一个python写的服务端代码,可以用浏览器当客户端去访问该服务端,理解web服务:

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午8:37
# @Author : Felix Wang import socket def handle_request(conn):
request_data = conn.recv(1024) print("request_data: ", request_data) # 观察并分析request_data值
conn.send("HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n<h1>Hello, World!</h1>".encode("utf8"))
# 响应首行\r\n响应头(可以有多个键值对,以\r\n分隔)\r\n\r\n响应体 def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8812)) # 绑定8812端口 sock.listen(5)
while True:
print("the server is waiting for client-connection....")
conn, addr = sock.accept()
handle_request(conn)
conn.close() if __name__ == '__main__':
main()

执行效果:

2、http协议

(1):协议简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web)服务器与本地浏览器之间传输超文本的传送协议。

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求,向客户端发送响应信息。

(2)、http协议特性

a、基于TCP/IP

HTTP协议是基于TCP/IP协议上的应用层协议。

b、基于请求-响应模式

HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

c、无状态保存

HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。

使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。可是,随着Web的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管理状态了。有关Cookie的详细内容稍后讲解。

d、无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

3、http请求协议与响应协议

http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的响应协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文做请求报文,响应端(服务器端)的做响应报文。HTTP报文本身是由多行数据构成的字符串文本。

(1):请求协议

请求格式,如下图:

请求方式:get与post

a、GET提交的数据会放在URL中的路径之后,以?分割路径和传输数据,参数之间以&相连,如EditBook?name=test&pwd=123;POST方法是把提交的数据放在HTTP包的请求体中;

b、GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制;

c、GET与POST请求在服务端获取请求数据方式不同;

示例:GET / HTTP/1.1\r\n Host: 127.0.0.1:8812\r\nUser-Agent: Mozilla/5.0...\r\n\r\n

(2)响应协议

响应格式,如下图:

示例:HTTP/1.1 200 OK\r\nstatus:200\r\nContent-Type:text/html\r\n\r\n<h1>Hello</h1>

响应状态码:状态码的职责是当客户端向服务器端发送请求时, 描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。状态码(如:200 OK)以3位数字和原因短语组成。数字中的第一位指定了响应类别,后两位无分类。响应类别有以下5种:

(3)代码实例

服务端:

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午9:10
# @Author : Felix Wang import socket sock = socket.socket()
sock.bind(("127.0.0.1", 8808))
sock.listen(5) while 1:
print("server waiting.....")
conn, addr = sock.accept()
data = conn.recv(1024)
print("request-data", data)
# 读取html文件
with open("login.html", "rb") as f:
data = f.read() conn.send((b"HTTP/1.1 200 OK\r\n\r\n%s" % data))
conn.close()

login.html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
  用户名 <input type="text" name="user">
  密码 <input type="password" name="pwd">
  <input type="submit">
</form>
</body>
</html>

4、web框架

Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法。web框架已经实现了很多功能,开发人员使用框架提供的方法并且完成自己的业务逻辑,就能快速开发web应用了。浏览器和服务器的是基于HTTP协议进行通信的。也可以说web框架就是在以上十几行代码基础张扩展出来的,有很多简单方便使用的方法,大大提高了开发的效率。

(1)、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协议开发的服务模块。

wsgire模块使用详解:

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午9:21
# @Author : Felix Wang
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>'] httpd = make_server('', 8080, application)
print('Serving HTTP on port 8080...')
# 开始监听HTTP请求:
httpd.serve_forever()

总结:wsgiref模块的主要作用是拆请求协议的包和封装响应格式。

(2)自己搭建一个web框架

目录结构:

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午9:38
# @Author : Felix Wang import pymysql conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='felixwang', db='mydb')
cur = conn.cursor() sql = '''
create table userinfo(
id INT PRIMARY KEY,
name VARCHAR(32),
password VARCHAR(32)
) '''
cur.execute(sql) conn.commit() cur.close()
conn.close()

models.py

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午10:03
# @Author : Felix Wang import pymysql from urllib.parse import parse_qs def login(environ):
if environ.get("REQUEST_METHOD") == "POST": try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0 request_body = environ['wsgi.input'].read(request_body_size)
data = parse_qs(request_body) user = data.get(b"user")[0].decode("utf8")
pwd = data.get(b"pwd")[0].decode("utf8") # 连接数据库
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='felixwang', db='mydb')
# 创建游标
cur = conn.cursor()
SQL = "select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'" % (user, pwd)
cur.execute(SQL) if cur.fetchone():
f = open("templates/backend.html", "rb")
data = f.read()
data = data.decode("utf8")
return data.encode("utf8")
else:
print("OK456")
return b"user or pwd is wrong" else:
f = open("templates/login.html", "rb")
data = f.read()
f.close()
return data

views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>welcome to myweb!</h4>
</body>
</html>

backend.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h4>登录页面</h4>
<form action="" method="post">
用户名 <input type="text" name="user">
密码 <input type="text" name="pwd">
<input type="submit">
</form> </body>
</html>

login.html

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午9:38
# @Author : Felix Wang from wsgiref.simple_server import make_server
from app01.views import *
import urls def routers():
URLpattern = urls.URLpattern
return URLpattern def applications(environ, start_response):
path = environ.get("PATH_INFO")
start_response('200 OK', [('Content-Type', 'text/html'), ('Charset', 'utf8')])
urlpattern = routers()
func = None
for item in urlpattern:
if path == item[0]:
func = item[1]
break
if func:
return [func(environ)]
else:
return [b"<h1>404!<h1>"] if __name__ == '__main__':
server = make_server("", 8080, applications)
print("Serving HTTP on port 8080...")
server.serve_forever()

manage.py

# -*- coding: utf-8 -*-
# @Time : 18-10-30 下午9:38
# @Author : Felix Wang from app01.views import * URLpattern = (
("/login/", login),
)

urls.py

my_web这个package就是一个web框架,下载这个web框架就可以快速实现一些简单的web功能,比如页面跳转。

5、Django简介

(1)、MVC与MTV模型

a、MVC

Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:

b、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)、Django的下载与基本命令

a、下载django

pip install

b、创建一个django project (django-admin.exe所在的目录要加入环境变量)

django-admin startproject mysite

注意:该命令在哪个文件夹执行,django项目就建在了哪个目录下

执行后生成mysite的工程,目录结构如下:

manage.py -- Django项目里面的工具,通过它可以调用django shell和数据库等。

settings.py -- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。

urls.py -- 负责把URL模式映射到应用程序。

c、在mysite目录下创建应用(要先进入manage.py统计目录)

python manage.py startapp blog

注意:一个项目中有多个应用,每个应用都有自己的业务逻辑

执行后,mysite目录下会生成blog这个应用,目录如下:

d、启动django项目(默认是8000)

python manage.py runserver 8000

这样我们的django就启动起来了!当我们访问:http://127.0.0.1:8000/时就可以看到:

(3)、基于Django实现简单实例

urls文件(url控制器):

from django.contrib import admin
from django.urls import path
from blog import views urlpatterns = [
path('admin/', admin.site.urls),
path('index/',views.index)
]

views文件(视图):

from django.shortcuts import render

# Create your views here.
import datetime def index(request):
now = datetime.datetime.now()
ctime = now.strftime("%Y-%m-%d %X")
return render(request, "index.html", {"ctime": ctime})

index.html(模板文件):若没有templates目录则手动创建,其中放html文件

<!DOCTYPE html> 
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>  
</head>
<body>
  <h4>当前时间:{{ ctime }}</h4>
</body>
</html>

访问效果:

注意:每一个视图函数都传一个request形参,封装了请求协议,并返回HttpResponse对象。

6、补充

(1)、url的组成

  协议://域名:端口号/路径?参数(键值对,如:user=name&pwd=123)

示例:https://www.baidu.com/s?wd=alex

(2)、Django框架问题

用命令创建完成后没有templates文件夹(存放html文件),需要手动创建,并且有些版本没有配置templates路径,需手动配置,方法如下:

找到settings.py文件中的TEMPLATES列表中的 'DIRS': [os.path.join(BASE_DIR, "templates")]

(3)、当使用django时,如果页面遇到forbidden错误时(post提交容易发生),就去settings.py文件中找到MIDDLEWARE列表的第3项'django.middleware.csrf.CsrfViewMiddleware',将其注释掉即可。

Django系列(一):前期准备的更多相关文章

  1. Django系列目录

    一:搭建自己的博客系列  搭建自己的博客(一):前期准备  搭建自己的博客(二):创建表,创建超级用户  搭建自己的博客(三):简单搭建首页和详情页 搭建自己的博客(四):优化首页和详情页 搭建自己的 ...

  2. Django 系列博客(十六)

    Django 系列博客(十六) 前言 本篇博客介绍 Django 的 forms 组件. 基本属性介绍 创建 forms 类时,主要涉及到字段和插件,字段用于对用户请求数据的验证,插件用于自动生成 h ...

  3. Django 系列博客(十四)

    Django 系列博客(十四) 前言 本篇博客介绍在 html 中使用 ajax 与后台进行数据交互. 什么是 ajax ajax(Asynchronous Javascript And XML)翻译 ...

  4. Django 系列博客(十三)

    Django 系列博客(十三) 前言 本篇博客介绍 Django 中的常用字段和参数. ORM 字段 AutoField int 自增列,必须填入参数 primary_key=True.当 model ...

  5. Django 系列博客(十二)

    Django 系列博客(十二) 前言 本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询. 聚合查询 语法:aggregate(*args, **kwargs) ...

  6. Django 系列博客(十一)

    Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...

  7. Django 系列博客(十)

    Django 系列博客(十) 前言 本篇博客介绍在 Django 中如何对数据库进行增删查改,主要为对单表进行操作. ORM简介 查询数据层次图解:如果操作 mysql,ORM 是在 pymysql ...

  8. Django 系列博客(九)

    Django 系列博客(九) 前言 本篇博客介绍 Django 模板的导入与继承以及导入导入静态文件的几种方式. 模板导入 模板导入 语法:``{% include '模板名称' %} 如下: < ...

  9. Django 系列博客(八)

    Django 系列博客(八) 前言 本篇博客介绍 Django 中的模板层,模板都是Django 使用相关函数渲染后传输给前端在显式的,为了想要渲染出我们想要的数据,需要学习模板语法,相关过滤器.标签 ...

  10. Django 系列博客(七)

    Django 系列博客(七) 前言 本篇博客介绍 Django 中的视图层中的相关参数,HttpRequest 对象.HttpResponse 对象.JsonResponse,以及视图层的两种响应方式 ...

随机推荐

  1. Scala Map与Tuple

    创建Map // 创建一个不可变的Map val ages = Map("Leo" -> 30, "Jen" -> 25, "Jack&q ...

  2. Java Embeded 包 与各个架构之间的关系

    Oracle Java Embedded Suite 7.0 for Linux x86        V37917-01.zip        Oracle Java Embedded Suite ...

  3. 偶数矩阵 Even Parity,UVa 11464

    题目描述 Description 给你一个n*n的01矩阵(每个元素非0即1),你的任务是把尽量少的0变成1,使得每个元素的上.下.左.右的元素(如果存在的话)之和均为偶数.如图所示的矩阵至少要把3个 ...

  4. python多线程爬取斗图啦数据

    python多线程爬取斗图啦网的表情数据 使用到的技术点 requests请求库 re 正则表达式 pyquery解析库,python实现的jquery threading 线程 queue 队列 ' ...

  5. 编写Postgres扩展之四:测试

    原文:http://big-elephants.com/2015-11/writing-postgres-extensions-part-iv/ 编译:http://big-elephants.com ...

  6. iOS - Scenekit3D引擎初探之 - 给材质贴图

    今天简单说一下 SceneKit 给材质贴图. 1,最简单的一种方法,直接打开dae 或者 scn 文件直接设置  如上图,这个dae 文件中只有一个几何体,几何体中只有一个材质球,然后设置材质球的d ...

  7. 将网址url中的参数转化为JSON格式的两种方法

    在我们进入主题前,我先先看下获取网址URL的方法: window.location.href // 设置或获取整个URL为字符串 window.location.hash // 设置或获取href属性 ...

  8. stm32 触摸屏 XPT2046

    引脚功能描述 控制字的控制位命令 控制字节各位描述 单端模式输入配置 差分模式输入配置 时序 前8个时钟用来通过DIN引脚输入控制字节,接着的12个时钟周期将完成真正的模数转换,剩下的3个多时钟周期将 ...

  9. 利用 pandas库读取excel表格数据

    利用 pandas库读取excel表格数据 初入IT行业,愿与大家一起学习,共同进步,有问题请指出!! 还在为数据读取而头疼呢,请看下方简洁介绍: 数据来源为国家统计局网站下载: 具体方法 代码: i ...

  10. MyEclipse修改运行内存

    修改  myeclipse.ini -vmargs -Xmx1768m -XX:MaxPermSize=1320m -XX:ReservedCodeCacheSize=64m -Dosgi.nls.w ...