HTTP协议
例如访问京东页面,输入网址即请求协议,服务器返回一个页面即响应协议
.
HTTP是无状态协议:
对于多个客户端发送的请求以及单个客户端多次发送请求,服务器只能识别请求无法识别客户端IP地址,即无状态协议
请求协议
客户端(浏览器)向服务器发送请求
.
浏览器将request header请求头一并发送给服务器,request header在浏览器审查元素Network中具体信息
用户信息放在请求体被浏览器发送给服务器
.
.
HTTP默认的请求方法就是GET1.没有请求体
2.数据必须在1K之内!
3.GET请求数据会暴露在浏览器的地址栏中
.
Get请求常用的操作:
1.在浏览器的地址栏中直接给出URL,那么就一定是GET请求
2.点击页面上的超链接也一定是GET请求
3.提交表单时,表单默认使用GET请求,但可以设置为POST
.
.
POST请求
1.数据不会出现在地址栏中
2.数据的大小没有上限
3.有请求体
4.请求体中如果存在中文,会使用URL编码
响应协议
服务器接收浏览器发送来的请求,并将页面内容返回给浏览器
.
若两次请求之间页面内容没有更新,则第二次访问URL时浏览器直接读取缓存的数据
Web框架
什么是web框架?
框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单的说,就是你用别人搭建好的舞台来做表演
对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端
.
框架就是别人设计好的东西直接拿来用,学框架要做到学会怎么用
Do a Web framework ourselves
自己写一个比较简单的框架(server),通过修改URL路径来实现框架中不同的函数,每一个函数实现的功能对应一个路径,
尝试通过自定义html向server发送请求,由server通过函数做出响应
代码实现:
# -*- coding:utf-8 -*-
'''
一个简单的框架
'''
from wsgiref.simple_server import make_server
import time
'''
application方法就是符合WSGI标准的一个HTTP处理函数,它接收两个参数
environ:一个包含所有HTTP请求信息的dict对象,
从environ中的键值对可以获取用户信息
start_response:一个发送HTTP响应的函数
'''
def foo1(req):
f = open('index2.html', 'rb')
data = f.read()
return data
def foo2(req):
f = open('index1.html', 'rb')
data = f.read()
return data
def login(req):
# QUERY_STRING是用户信息的键值对
print(req['QUERY_STRING'])
return b'welcome'
def signup(req):
pass
def response(req):
return b"please input the url you need."
def show_time(req):
# 将数据库中的动态数据赋给times
times = time.ctime()
# 此处return 后面不加[],因为后面响应时调用函数加上了[]
# return ('<h1>time:%s</h1>'%str(times)).encode('utf8')
f = open('show_time.html', 'rb')
data = f.read()
# decode()将字节串转换成字符串,方便进行replace操作
data = data.decode('utf8')
# 将.html中{{time}}替换成times,此时times时间是数字,需str()转换
data = data.replace('{{time}}', str(times))
return data.encode('utf8')
'''
加一个路由写一个函数
'''
def router():
url_patterns = [
("/login", login),
("/signup", signup),
('/foo1', foo1),
('/foo2', foo2),
('/show_time', show_time)
]
return url_patterns
def application(environ, start_response):
# 获取URL路径后的值
print('path', environ["PATH_INFO"])
path = environ["PATH_INFO"]
# 响应头通过start_response设定
start_response('200 OK', [('Content-Type', 'text/html')])
url_patterns = router()
func = None
for item in url_patterns:
if item[0] == path:
func = item[1]
break
if func:
return [func(environ)]
else:
return [b'please input the url you need.']
# 服务器接收请求并调用application方法来做出响应
httpd = make_server('', 8080, application)
print('Serving HTTP on port 8080...')
# 开始监听HTTP请求: 服务器监听浏览器请求,输入127.0.0.1:8080URL向服务器发送请求
httpd.serve_forever()
server 端接收请求并打印信息如下
相应的html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{margin:0;padding:0}
</style>
</head>
<body>
<form action="http://127.0.0.1:8080/login" method="get">
<p>用户名<input type="text" name="user"/></p>
<p>密码<input type="password" name="pwd"/></p>
<p><input type="submit"/>提交</p>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{margin:0;padding:0}
</style>
</head>
<body>
<h1> Hello yueqi</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{margin:0;padding:0}
</style>
</head>
<body>
<h1> Hello yuejinzhao</h1>
</body>
</html>
MVC和MVC模式
M:model(模型)
V:view(视图)
C:controler(控制器)
以上面框架为例
URL控制器
'''
加一个路由写一个函数
'''
def router():
url_patterns = [
("/login", login),
("/signup", signup),
('/foo1', foo1),
('/foo2', foo2),
('/show_time', show_time)
]
return url_patterns
view视图函数
def foo1(req):
f = open('index2.html', 'rb')
data = f.read()
return data
def foo2(req):
f = open('index1.html', 'rb')
data = f.read()
return data
def login(req):
# QUERY_STRING是用户信息的键值对
print(req['QUERY_STRING'])
return b'welcome'
def signup(req):
pass
def response(req):
return b"please input the url you need."
def show_time(req):
# 将数据库中的动态数据赋给times
times = time.ctime()
# 此处return 后面不加[],因为后面响应时调用函数加上了[]
# return ('<h1>time:%s</h1>'%str(times)).encode('utf8')
f = open('show_time.html', 'rb')
data = f.read()
# decode()将字节串转换成字符串,方便进行replace操作
data = data.decode('utf8')
# 将.html中{{time}}替换成times,此时times时间是数字,需str()转换
data = data.replace('{{time}}', str(times))
return data.encode('utf8')
重点是
1.怎样使用python语言去调用数据库数据到model中,再从model中获取数据到view视图
2.怎样将视图函数功能进行渲染并将其返回给Template模板进而以html的形式返回给用户
Django框架的使用流程
windows下创建django项目
打开cmd命令行输入命令:
输入命令dir查看项目下的文件
在此项目创建一个blog应用
虽然在pycharm下创建项目很简单,但是创建django项目的命令是需要记住的
pycharm下django的流程
创建一个django项目,并在此项目目录下创建一个blog项目项目创建完成,可以看到urls.py , settings.py, models.py,等等文件
urls.py 用于存放用户需要访问的路径url 即控制器
views.py 用于存放实现相应功能的函数, 即视图
在django项目开发中需要将功能实现进行渲染放入模板进而以html文档的形式呈现给用户,就必须要用到html文件,此处templates 目录用于存放html文件
打开django Terminal 输入命令:python manage.py runserver 8080 (端口号自定义)
服务器运行成功显示如下图:
此时打开浏览器在url栏中输入地址127.0.0.1:8080/show_time即可访问
一个简单的django流程就完成了
static
在django项目开发过程中需要用到js的渲染,如下对于django如何找到js文件进行详细介绍
首先创建一个static目录,在初始的django项目目录下创建, django11右击 new -> python package
目录名字自定义
创建完成后,需要在settings.py 中进行设置让django能够找到js文件
此处的 STATIC_URL = ‘/static/’ 是别名,无论自定义创建的目录是什么名字,
只要此处的别名不改,在引用时只需引用static即可,此处static指目录名
对于js的引用
建议将static目录放在每一个应用里面
.
.
.
.
.
Django URL(路由系统)
eg:regist注册页面
url(r'article/(\d{4})$', views.article_year),
django 通过a标签找到路由访问数据库并将找到的文章返回给页面供用户阅读
url地址栏访问: 127.0.0.1:8080:article/四位数 ,
符号表示以
符
号
表
示
以
前的正则表达式为结尾
.
.
.
.
.
url(r'article/(?P<year>\d{4})/(?P<month>\d{2})', views.article_year_month),
有名分组: ?P<正则表达式对应的参数名>
此时url地址必须为: 127.0.0.1:8080:article/四位数/两位数
django的路由系统
urls.py
'''
无命名分组:
url(参数1:正则表达式,views视图函数,参数,别名)
有名分组:
?P<year> ?P<month>
'''
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^show_time/', views.show_time),
url(r'^login/', views.login),
# url地址栏路径article/四位数/两位数
# (\d{4})$分组后该正则表达式就可以作为参数传参,$表示必须以该正则结尾
url(r'article/(\d{4})$', views.article_year),
url(r'article/(?P<year>\d{4})/(?P<month>\d{2})', views.article_year_month),
url(r'regist', views.regist, name="reg")
]
views.py
def article_year(req, y):
return HttpResponse(y)
def article_year_month(req, year, month):
return HttpResponse("year:%s month:%s"%(year, month))
def regist(req):
# 走POST请求
if req.method == "POST":
# 打印form表单提交的信息
print(req.POST.get('user'))
print(req.POST.get('age'))
return HttpResponse('success!')
return render(req, 'regist.html')
regist.html
<!DOCTYPE html>
<html lang="en">
<head>
/*注意引用*/
{% load staticfiles %}
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>注册</h1>
<!--此处在表单点击提交后django默认将浏览器当前IP地址加到别名reg前面-->
<form action="{% url 'reg' %}" method="post">
<p>姓名:<input type="text" name="user" /></p>
<p>年龄:<input type="text" name="age"/></p>
<p>
爱好:<input type="checkbox" name="hobby" value="1"/>篮球
<input type="checkbox" name="hobby" value="2"/>足球
<input type="checkbox" name="hobby" value="3"/>乒乓
</p>
<p><input type="submit"/></p>
</form>
</body>
</html>
django的路由系统基本原理
输入python manage.py runserver 8082 通过8082端口打开服务器
1.首先通过url 127.0.0.1:8082:/regist 访问注册页面
2.django 通过路由url找到发送GET请求的路径,并匹配对应的视图函数
3.通过视图函数功能做出响应,返回注册页面给用户,用户在注册页面输入用户信息,通过表单的post请求发送数据
4.form表单识别路径的别名reg,并再一次通过POST请求发送数据
5.django 接收数据包并在后台打印数据,完成响应请求
路由分发
在django项目目录下的 urls.py 加上路由分发防止一个应用路由错误影响其他应用运行
django项目下 urls.py
#include 为路由分发
from django.conf.urls import url, include
from django.contrib import admin
from blog import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^show_time/', views.show_time),
url(r'^login/', views.login),
# 路由的分发
url(r'blog/', include('blog.urls')),
]
blog应用下 urls.py
from django.conf.urls import url,include
from django.contrib import admin
from blog import views
urlpatterns = [
url(r'article/(\d{4})$', views.article_year),
url(r'article/(?P<year>\d{4})/(?P<month>\d{2})', views.article_year_month),
url(r'regist', views.regist, name="reg"),
]
路由分发后 对于路径的改变