Django(二) 视图View知识点
1.url匹配的过程
2.定义视图函数
request参数必须有。是一个HttpRequest类型的对象。视图必须返回HttpResponse对象,HttpResponse中的参数内容会显示在浏览器的页面上。也可能重定向redirect,还可以返回json数据。
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader,RequestContext
# 视图调用模板
'''
1.找到模板
2.定义上下文
3.渲染模板
'''
def my_render(request, template_path, context_dict={}):
# 使用模板文件
# 1.加载模板文件,模板对象
temp = loader.get_template(template_path)
# 2.定义模板上下文:给模板传递数据
context = RequestContext(request, context_dict)
# 3.模板渲染:产生标准的Html内容
res_html = temp.render(context)
# 4.返回浏览器
return HttpResponse(res_html)
# http://127.0.0.1:8000/index
def index(request):
# 进行处理,和M和T进行交互,content是给前端传的参数
return my_render(request, 'booktest/index.html',{'content':'hello word', 'list':list(range(1,10))})
# http://127.0.0.1:8000/index2
def index2(request):
return HttpResponse('老铁666')
3.进行url配置,建立url地址和视图的对应关系
在应用中定义URLconf,booktest/应用下创建urls.py文件
from django.conf.urls import url
from booktest import views
# 通过url函数设置url路由配置项
urlpatterns = [
# 建立/index和视图index之间的关系
url(r'^index$', views.index),
url(r'^index2$', views.index2),
]
将应用包含到项目中:打开test1/urls.py文件,为urlpatterns列表增加项如下:
from django.conf.urls import include, url
from django.contrib import admin
# 项目的urls文件
urlpatterns = [
# 配置项目
url(r'^admin/', include(admin.site.urls)),
# 包含booktest应用中的urls文件
url(r'^', include('booktest.urls')),
]
4.创建模版
为应用booktest下的视图index创建模板index.html,目录结构如下图:
设置查找模板的路径:打开test1/settings.py文件,设置TEMPLATES的DIRS值
# 设置模板路径
'DIRS': [os.path.join(BASE_DIR, 'templates')],
设置自动加载 修改test1/init.py
import pymysql
pymysql.install_as_MySQLdb()
5.定义模板
修改templtes/booktest/index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板文件</title>
</head>
<body>
<h1>这是一个模板</h1>
使用模板变量<br/>
{{ content }}
<br/>
{{ list }}
</body>
</html>
6.访问
HttpReqeust对象
服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,这个对象不需要我们创建,直接使用服务器构造好的对象就可以。视图的第一个参数必须是HttpRequest对象,在django.http模块中定义了HttpRequest对象的API。
POST:提交的参数请求头。数据安全性要求比较高的时候使用post.
GET:提交的参数在url中。
属性
下面除非特别说明,属性都是只读的。
• path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
• method:一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’、‘POST’。
• 在浏览器中给出地址发出请求采用get方式,如超链接。
• 在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求。
• encoding:一个字符串,表示提交的数据的编码方式。
• 如果为None则表示使用浏览器的默认设置,一般为utf-8。
• 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
• GET:QueryDict类型对象,类似于字典,包含get请求方式的所有参数。
• POST:QueryDict类型对象,类似于字典,包含post请求方式的所有参数。
• FILES:一个类似于字典的对象,包含所有的上传文件。
• COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串。
• session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见"状态保持"。
捕获url参数
进行url匹配时,把所需要的捕获的部分设置成一个正则表达式组,这样django框架就会自动把匹配成功后相应组的内容作为参数传递给视图函数。
- 位置参数
位置参数,参数名可以随意指定
# 捕获url参数:位置参数
url(r'^showarg(\d+)$', views.show_arg),
- 关键字参数:在位置参数的基础上给正则表达式组命名即可。
?P<组名>
关键字参数,视图中参数名必须和正则表达式组名一致.
# 捕获url参数:关键字参数
url(r'^showarg(?P<num>\d+)$', views.show_arg),
定义视图
def show_arg(request, num):
return HttpResponse(num)
form表单示例
1)打开booktest/views.py文件,创建视图
def login(request):
'''显示登录页面'''
return render(request, 'booktest/login.html')
def login_check(request):
'''登录校验视图'''
# request.POST 保存的是post方式提交的参数QueryDict
# request.GET 保存是get方式提交的参数
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'smart' and password == '123':
# 用户名密码正确,跳转到首页
response = redirect('/index')
return response
else:
# 用户名或密码错误,跳转到登录页面
return redirect('/login')
2)打开booktest/urls.py文件,配置url。
# 显示登录页面
url(r'^login$', views.login),
# 用户登录校验
url(r'^login_check$', views.login_check),
3)修改templates/booktest目录下的login.html,添加代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<form method="post" action="/login_check">
用户名:<input type="text" name="username" value="{{ username }}"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
解释:使用form表单请求时,method方式为post则会发起post方式的请求,需要使用HttpRequest对象的POST属性接收参数,POST属性是一个QueryDict类型的对象。
表单form如何提交参数的?
答:表单控件name属性的值作为键,value属性的值为值,构成键值对提交。
• 如果表单控件没有name属性则不提交。
• 对于checkbox控件,name属性的值相同为一组,被选中的项会被提交,出现一键多值的情况。
• 键是表单控件name属性的值,是由开发人员编写的。
• 值是用户填写或选择的。
4)运行服务器。
HttpResponse对象
视图在接收请求并处理后,必须返回HttpResponse对象或子对象。在django.http模块中定义了HttpResponse对象的API。HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。
JsonResponse
在浏览器中使用javascript发起ajax请求时,返回json格式的数据,此处以jquery的get()方法为例。类JsonResponse继承自HttpResponse对象,被定义在django.http模块中,创建对象时接收字典作为参数。
JsonResponse对象的content-type为'application/json'
重定向 HttpResponseRedirect
Django中提供了HttpResponseRedirect对象实现重定向功能,这个类继承自HttpResponse,被定义在django.http模块中,返回的状态码为302
示例
1)在booktest/views.py文件中定义视图red1,代码如下:
from django.http import HttpResponseRedirect
...
# 定义重定义向视图,转向首页
def index(request):
return HttpResponseRedirect('/login')
重定向简写函数redirect
在django.shortcuts模块中为重定向类提供了简写函数redirect。
1)修改booktest/views.py文件中red1视图,代码如下:
from django.shortcuts import redirect
...
def index(request):
return redirect('/login')
Cookie
Cookie的特点
• Cookie以键值对的格式进行信息的存储。
• Cookie基于域名安全,不同域名的Cookie是不能互相访问的,如访问itcast.cn时向浏览器中写了Cookie信息,使用同一浏览器访问baidu.com时,无法访问到itcast.cn写的Cookie信息。
• 当浏览器请求某网站时,会将浏览器存储的跟网站相关的所有Cookie信息提交给网站服务器。
• cookie是有过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。
• cookie是由服务器生成,存储在浏览器端的一小段文本信息。
典型应用:记住用户名,网站的广告推送。
设置Cookie
1)打开booktest/views.py文件,创建视图set_cookie
def set_cookie(request):
'''设置cookie信息'''
response = HttpResponse('设置cookie')
# 设置一个cookie信息,名字为num, 值为1,保存时间2周
response.set_cookie('num', 1, max_age=14*24*3600)
# 返回response
return response
2)打开booktest/urls.py文件,配置url。
url(r'^set_cookie$',views.set_cookie),
3)在浏览器输入如下网址。
http://127.0.0.1:8000/set_cookie/
读取Cookie
Cookie信息被包含在请求头中,使用request对象的COOKIES属性访问。
1)打开booktest/views.py文件,创建视图get_cookie
def get_cookie(request):
'''获取cookie的信息'''
# 取出cookie num的值
num = request.COOKIES['num']
return HttpResponse(num)
2)打开booktest/urls.py文件,配置url。
url(r'^get_cookie$',views.get_cookie),
3)在浏览器输入如下网址。
http://127.0.0.1:8000/get_cookie/
Session
session的特点
• session是以键值对进行存储的
• session依赖于cookie。唯一的标识码保存在sessionid cookie中
• session也是有过期时间,如果不指定,默认两周就会过期
• session存储在服务器端
典型应用:对于敏感、重要的信息,建议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息。
依赖于Cookie
所有请求者的Session都会存储在服务器中,服务器如何区分请求者和Session数据的对应关系呢?
答:在使用Session后,会在Cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid后,会根据这个值找出这个请求者的Session。
结果:如果想使用Session,浏览器必须支持Cookie,否则就无法使用Session了。
存储Session时,键与Cookie中的sessionid相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置。
启用Session
Django项目默认启用Session。
存储方式
打开test3/settings.py文件,设置SESSION_ENGINE项指定Session数据存储的方式,可以存储在数据库、缓存、Redis等。
1)存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。
SESSION_ENGINE='django.contrib.sessions.backends.db'
2)存储在缓存中:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE='django.contrib.sessions.backends.cache'
3)混合存储:优先从本机内存中存取,如果没有则从数据库中存取。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
4)如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用。
5)迁移后会在数据库中创建出存储Session的表。
6)表结构如下图。
由表结构可知,操作Session包括三个数据:键,值,过期时间。
设置session
1)打开booktest/views.py文件,创建视图set_session,代码如下:
def set_session(request):
'''设置session'''
request.session['username'] = 'smart'
request.session['age'] = 18
# request.session.set_expiry(5)
return HttpResponse('设置session')
2)打开booktest/urls.py文件,配置url。
url(r'^set_session$',views.set_session),
3)运行服务器,打开浏览器请求如下网址。
http://127.0.0.1:8000/set_session/
4)浏览效果如下图,在"开发者工具"中可以查看到响应头中创建了Cookie,里面有个键为sessionid。
读取session
1)打开booktest/views.py文件,修改get_session视图如下:
def get_session(request):
'''获取session'''
username = request.session['username']
age = request.session['age']
return HttpResponse(username+':'+str(age))
2)打开booktest/urls.py文件,配置url。
url(r'^get_session$',views.get_session),
3)运行服务器,打开浏览器请求如下网址。
http://127.0.0.1:8000/get_session/
4)刷新浏览器效果如下图。
删除Session
1)打开booktest/views.py文件,修改clear_session视图如下
def clear_session(request):
'''清除session信息'''
request.session.clear()
return HttpResponse('清除成功')
2)刷新浏览器,在数据库命令行中查询,base64解码后如下图。
使用Redis存储Session
会话还支持文件、纯cookie、Memcached、Redis等方式存储,下面演示使用redis存储。
1)安装包。
pip install django-redis-sessions==0.5.6
2)修改test3/settings文件,增加如下项:
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 2
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'
3)打开booktest/views.py文件,修改session_test视图如下:
def session_test(request):
request.session['h1']='hello'
return HttpResponse('ok')
4)管理redis的命令,需要保证redis服务被开启。
查看:ps ajx|grep redis
启动:sudo service redis start
停止:sudo service redis stop
使用客户端连接服务器:redis-cli
切换数据库:select 2
查看所有的键:keys *
获取指定键的值:get name
5)刷新浏览器,在redis客户端中查看数据如下。
Session共享
1. 基于Nginx的ip_hash负载均衡
这个方案实现最为简单,只要hash属性是均匀的,多台web服务器的负载就是均衡的,安全性高,缺点:用户浏览器的IP地址hash以后满足单调性。会可能造成资源的分配不均衡,负载均衡就达不到到目的。有的服务器负载过重,有的服务器负载过轻,显然没有充分利用资源。
2. 基于数据库的Session共享
首选当然是大名鼎鼎的Mysql数据库,并且建议使用内存表Heap,提高session操作的读写效率。这个方案的实用性比较强,相信大家普遍在使用,它的缺点在于session的并发读写能力取决于Mysql数据库的性能,同时需要自己实现session淘汰逻辑,以便定时从数据表中更新、删除 session记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不否认使用数据库存储Session还是有些杀鸡用牛刀的架势。
3. 将信息放到cookie放在客户端
session存在服务器端,会对服务器产生压力。如果将信息保存到cookie中,减轻了服务器的压力,同时每个客户端的压力也很小。因为只保存自己的信息。这种方式在实际的开发中广泛的采用。
缺点:cookie可以被禁用,cookie要随着浏览器传递,增大了传输的内容,cookie大小有限制。
4. 基于Redis做缓存session的统一缓存
其实就是把每次用户的请求的时候生成的sessionID给放到Redis的服务器上。然后在基于Redis的特性进行设置一个失效时间的机制,这样就能保证用户在我们设置的Redis中的session失效时间内,都不需要进行再次登录。
ajax
可模拟任何请求方式向后端发送请求
$.ajax({
url:'地址',
type:'GET',
data:{...},
success:function(arg){
console.log(arg);
}
})