django框架视图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hard_days/article/details/88384498

视图

1. 视图的功能

接收请求,进行处理,与M和T进行交互,返回应答。

返回html内容 HttpResponse,也可能重定向 redirect,还可以返回json数据。

1.1创建案列项目

1、创建项目django-admin startproject demo3

2、创建应用python manage.py startapp app1

3、注册应用 ,打开demo3下的settings文件,设置如下信息

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app1',
)

4、配置数据库,先在项目目录下面的__init__文件添加如下代码

import pymysql
pymysql.install_as_MySQLdb()

再在demo3下的settings文件,设置如下信息

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'demo3', # 指定数据库名字
        'USER':'root',
        'PASSWORD':'mysql',
        'PORT':3306,
        'HOST':'localhost'
    }
}

5、创建模型类

在应用目录下的models.py定义如下代码

class NewsInfo(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()

6、生成迁移python manage.py makemigrations

7、执行迁移python manage.py migrtion

8、新建模板文件、

在项目目录下新建一个名为tamplates的文件夹,在该文件夹下面新建一个和应用同名的文件夹app1,

9、修改模板路径

设置查找模板的路径:打开settings.py文件,设置TEMPLATES的DIRS值

'DIRS': [os.path.join(BASE_DIR, 'templates')],

1.2. 视图函数使用

视图就是一个python函数,被定义在"应用/views.py"文件中。 使用视图时需要进行两方面操作,两个操作不分先后。

1)在"应用/views.py"中定义视图,

视图 函数request参数必须有。返回的是一个HttpRequest类型的对象。参数名可以变化。

在app1/views.py中定义视图函数index:

from django.shortcuts import render
​
# Create your views here.
from django.http import  HttpResponse
​
def index(request):
    return HttpResponse('<h1>个是新定义的视图index<h1>')

2)配置URLconf,将视图函数和url对应起来

1) 在项目的urls文件中包含具体应用的urls文件,在具体应用的urls文件中包含具体url和视图的对应关系。

2) url配置项是定义在一个名叫urlpatterns的列表中,其中的每一个元素就是一个配置项,每一个配置项都调用url函数。

在项目目录下的urls.py中编辑加入如下代码:

from django.conf.urls import include, url
from django.contrib import admin
​
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^', include('app1.urls')), #这句代码是新加入的,包含app1应用中的urls文件
]

在应用目录下创建urls.py文件并编辑其内容如下:

from django.conf.urls import url #导入url函数
​
from .views import * #导入视图模块
​
urlpatterns = [
    url(r'^$',index), #建立url和index视图函数的关联
]

1.3启动服务器,

启动项目命令python manage.py runserver

并通过浏览器访问定义的视图页面

2. url匹配的过程

用户通过在浏览器的地址栏中输入网址请求网站,对于Django开发的网站,由哪一个视图进行处理请求,是由url匹配找到的。

2.1、配置

1、在项目目录下的/settings.py中通过ROOT_URLCONF指定url配置,默认已经有此配置。

ROOT_URLCONF = 'demo3.urls'

2、打开demo3/urls.py可以看到默认配置

from django.conf.urls import url,include
​
urlpatterns = [
    url(r'admin/',include(admin.site.urls)),
    
]

注意点

  • 在项目目录下的urls.py中进行包含配置,在各自应用中创建具体配置。

  • 在urls里面定义urlpatterns列表,存储url()对象,这个名称是固定的。urlpatterns中的每个正则表达式在第一次访问它们时被编译,这使得运行很快

2.2、语法

url()对象,被定义在django.conf.urls包中,有两种语法结构:

语法一:包含,一般在自定义应用中创建一个urls.py来定义url。

这种语法用于demo3/urls.py中,目的是将项目的urls配置到应用内部,数据更清晰并且易于维护。

url(正则,include('应用.urls'))

1)如示例在test3/urls.py文件,包含app1中的urls。

url(r'^',include('app1.urls')),

语法二:定义,指定URL和视图函数的对应关系。

在应用内部创建urls.py文件,指定请求地址与视图的对应关系。

url(正则,'视图函数名称')

1)如示例在app1/urls.py中创建首页的url,代码如下

from django.conf.urls import url
from .views import *
urlpatterns = [
    url(r'^$',index),
    url(r'^index$',index)
]

2)如示例在app1/views.py中创建视图index

from django.shortcuts import render
from django.http import HttpResponse
def index(requuest):
    return HttpResponse('<h1>这个是新定义的视图index<h1>')

说明1:正则部分推荐使用r,表示字符串不转义,这样在正则表达式中使用\只写一个就可以。

说明2:不能在开始加反斜杠,推荐在结束加反斜杠。

正确:index/
正确:index
错误:/index
错误:/index/

2.3、捕获url中的参数

请求的url被看做是一个普通的python字符串,进行匹配时不包括域名、get或post参数。 如请求地址如下:

http://172.0.0.1:8000/index1/

1)去除掉域名和参数部分,并将最前面的/去除后,只剩下如下部分与正则匹配。

index/

2)打开app1/urls.py文件,定义与这个地址匹配的url如下:

url(r'^index\d+/$',show1),

3)在app1/views.py中创建视图show。

def show(request):
    return HttpResponse('这个是show视图')

4)启动服务器,输入上面的网址,浏览器中效果如下图

http://172.0.0.1:8000/index1/

可以在匹配过程中从url中捕获参数,每个捕获的参数都作为一个普通的python字符串传递给视图。

获取值需要在正则表达式中使用小括号,分为两种方式:

  • 位置参数

  • 关键字参数

注意:两种参数的方式不要混合使用,在一个正则表达式中只能使用一种参数方式。

方式一:位置参数

直接使用小括号,通过位置参数传递给视图。

1)为了提取参数,修改上面的正则表达式如下:

url(r'^index(\d+)/$',views.show_arg),

2)修改视图show如下:

def show(request,num):
    return HttpResponse('这个是show返回的页面,index后面的num:%s'%num)
​

3)刷新浏览器页面,效果如下图:

方式二:关键字参数

在正则表达式部分为组命名。

1)修改正则表达式如下:

其中?P部分表示为这个参数定义的名称为id,可以是其它名称,起名做到见名知意。

url(r'^index(?P<name1>\d+)/$',show),

2)修改视图show如下:

注意:视图show此时必须要有一个参数名为name1,否则报错。

def show(request,name1):
    return HttpResponse('这个是show返回的页面,index后面的num:%s'%name1)
​

3)刷新浏览器页面,效果如下图

3、错误视图

Django内置处理HTTP错误的视图,主要错误及视图包括:

  • 404错误:url匹配失败,找不到页面

  • 500错误:server error视图

如果想看到错误视图而不是调试信息,需要修改test3/setting.py文件的DEBUG项。

DEBUG = False
ALLOWED_HOSTS = ['*', ]

404错误及视图

将请求地址进行url匹配后,没有找到匹配的正则表达式,则调用404视图,这个视图会调用404.html的模板进行渲染。视图传递变量request_path给模板,表示导致错误的URL。

1)在templates中创建404.html。

2)定义代码如下:

<html>
<head>
    <title></title>
</head>
<body>
找不到该页面
<hr/>
{{request_path}}
</body>
</html>

3)在浏览器中输入如下网址:

http://127.0.0.1:8000/test/

4)运行效果如下图:

500错误及视图

在视图中代码运行报错会发生500错误,调用内置错误视图,使用templates/500.html模板渲染。

更改views.py的show函数,故意出错,

def show(request,num):
    print(a)   #  a 没定义  代码这里会报错
    return HttpResponse('这个是show返回的页面,index后面的num:%s'%num)
​

访问下面页面,调用show视图函数,出错,返回500页面

4、HttpReqeust对象

服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,这个对象不需要我们创建,直接使用服务器构造好的对象就可以。视图的第一个参数必须是HttpRequest对象,在django.http模块中定义了HttpRequest对象的API。

属性

下面除非特别说明,属性都是只读的。

  • 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 启用会话的支持时才可用,详细内容见"状态保持"。

  • 运行服务器,在浏览器中浏览首页,可以在浏览器“开发者工具”中看到请求信息如下图

示例

接下来演示属性path、method、encoding,对于GET、POST、FILES、COOKIES、session后面会有详细讲解。

path、encoding

1)打开app1/views.py文件,代码如下:

示例

接下来演示属性path、method、encoding,对于GET、POST、FILES、COOKIES、session后面会有详细讲解。

path、encoding

1)打开app1/views.py文件,代码如下:

def index(request):
    str1 = 'paht:{}---method:{}----encoding:{}'.format(request.path,request.method,request.encoding)
    return HttpResponse(str1)

2)打开浏览器请求,运行效果如下图:

method

1)打开app1/views.py文件,修改index,并且编写函数method_show,代码如下:

def index(request):
    return render(request,'app1/index.html')
​
def method_show(request):
    return HttpResponse(request.method)

2)打开app1/urls.py文件,新增配置如下:

    url(r'^method_show/$', views.method_show),

3)在templates/app1/下创建index.html文件,添加代码如下:

<html>
<head>
    <title>首页</title>
</head>
<body>
​
<a href='/method_show/'>get方式</a><br/>
<form method="post" action="/method_show/">
    <input type="submit" value="post方式">
</form>
<br/>
</body>
</html>

4)打开浏览器,输入如下网址:

http://127.0.0.1:8000/

5)浏览效果如下图:

6)点击链接,转到method_show,浏览效果如下图:

7) 回到method_test页面,点击按钮,转到method_post,浏览效果如下图,报错了。

8)打开test3/settings.py文件,将MIDDLEWARE_CLASSES项的csrf注释。

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
   # 'django.middleware.csrf.CsrfViewMiddleware',  # 把此行注释掉
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

9)回到浏览器中刷新,浏览效果如下图,点击“继续”按钮。

10)最终浏览效果如下图:

4.1、QueryDict对象

  • 定义在django.http.QueryDict

  • HttpRequest对象的属性GET、POST都是QueryDict类型的对象

  • 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况

  • 方法get():根据键获取值

  • 如果一个键同时拥有多个值将获取最后一个值

  • 如果键不存在则返回None值,可以设置默认值进行后续处理

dict.get('键',默认值)
可简写为
dict['键']
  • 方法getlist():根据键获取值,值以列表返回,可以获取指定键的所有值

  • 如果键不存在则返回空列表[],可以设置默认值进行后续处理

dict.getlist('键',默认值)

4.2、GET属性

请求格式:在请求地址结尾使用?,之后以"键=值"的格式拼接,多个键值对之间以&连接。

例:网址如下

https://www.baidu.com/s?wd=python&a=1&b=2

其中的请求参数为:

a=1
b=2
wd=python
  • 分析请求参数,键为'a'、'b'、'wd',值为'10'、'20'、'python'。

  • 在Django中可以使用HttpRequest对象的GET属性获得get方方式请求的参数。

  • GET属性是一个QueryDict类型的对象,键和值都是字符串类型。

  • 键是开发人员在编写代码时确定下来的。

  • 值是根据数据生成的。

4.3、POST属性

使用form表单请求时,method方式为post则会发起post方式的请求,需要使用HttpRequest对象的POST属性接收参数,POST属性是一个QueryDict类型的对象。

问:表单form如何提交参数呢?

答:表单控件name属性的值作为键,value属性的值为值,构成键值对提交。

  • 如果表单控件没有name属性则不提交。

  • 对于checkbox控件,name属性的值相同为一组,被选中的项会被提交,出现一键多值的情况。

  • 键是表单控件name属性的值,是由开发人员编写的。

  • 值是用户填写或选择的。

示例

1)打开app1/views.py文件,修改视图函数method_show

#接收请求参数
def methos_show(request):
    if request.method == 'GET':
        a = request.GET.get('a') #获取请求参数a
        b = request.GET.get('b') #获取请求参数b
        c = request.GET.get('c') #获取请求参数c
        content = {'a':a,'b':b,'c':c}
        return render(request, 'app1/get.html', content)
    else:
        name = request.POST.get('id') #获取账号
        password = request.POST.get('pw') #获取密码
        return render(request, 'app1/post.html', locals())

2)修改templates/app1目录下的index.html,添加代码如下:

<html>
<head>
    <title>首页</title>
</head>
<body>
<h2>提交数据的两种方式:<h2><br>
get方式:<br/>
<a href="/method_show/?a=99&b=88&c=python">get方式提交数据</a><br/>
​
post方式:<br/>
<form method="post" action="/method_show/">
    账号:<input type="text" name="name"><br/>
    密码:<input type="password" name="password">
   
    <input type="submit" value="提交">
</form>
<br/>
</body>
</html>

4)运行服务器。

http://127.0.0.1:8000/

浏览效果如下图:

5)在templates/app1目录下创建method.html,代码如下:

get.html:

<html>
<head>
    <title>GET方式提交数据</title>
</head>
<body>
<h1>get提交的数据</h1>
a:{{ a }}<br/>
b:{{ b }}<br/>
c:{{ c }}<br/>
</body>
</html>

post.html:

<html>
<head>
    <title>post</title>
</head>
<body>
​
<h1>post方式提交数据</h1>
​
提交的账号:{{ name }}<br/>
提交的密码:{{ password }}<br/>
</body>
</html>

6)点击链接GET方式提交数据,浏览效果如下图:

7)后退到index页面,输入数据如下,点击提交,浏览效果如下图:

5、HttpResponse对象

视图在接收请求并处理后,必须返回HttpResponse对象或子对象。在django.http模块中定义了HttpResponse对象的API。HttpRequest对象由Django创建,HttpResponse对象由开发人员创建。

运行服务器,在浏览器中浏览首页,可以在浏览器“开发者工具”中看到响应信息如下图:

标号3为响应头信息,点击标号4处可以查看响应体信息。

属性

  • content:表示返回的内容。

  • charset:表示response采用的编码字符集,默认为utf-8。

  • status_code:返回的HTTP响应状态码。

  • content-type:指定返回数据的的MIME类型,默认为'text/html'。

方法

  • _init_:创建HttpResponse对象后完成返回内容的初始化。

  • set_cookie:设置Cookie信息。

    set_cookie(key, value='', max_age=None, expires=None)
  • cookie是网站以键值对格式存储在浏览器中的一段纯文本信息,用于实现用户跟踪。

    • max_age是一个整数,表示在指定秒数后过期。

    • expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期。

    • max_age与expires二选一。

    • 如果不指定过期时间,在关闭浏览器时cookie会过期。

  • delete_cookie(key):删除指定的key的Cookie,如果key不存在则什么也不发生。

  • write:向响应体中写数据。

5.1、子类JsonResponse

在浏览器中使用javascript发起ajax请求时,返回json格式的数据,此处以jquery的get()方法为例。类JsonResponse继承自HttpResponse对象,被定义在django.http模块中,创建对象时接收字典作为参数。

JsonResponse对象的content-type为'application/json'。

示例

1)在app1/views.py文件中定义视图json1、json2,代码如下:

from django.http import JsonResponse
...
def json1(request):
    return render(request,'app1/json1.html')
def json2(request):
    return JsonResponse({'h1':'hello','h2':'world'})

2)在app1/urls.py文件中配置url。

    url(r'^json1/$', views.json1),
    url(r'^json2/$', views.json2),

5.2、ajax动态加载数据案列

在上面5.1的基础上进行下面的步骤,完成ajax请求加载数据

3在项目下创建目录static/js/,把jquery文件拷贝到这个目录下。

4)打开app1/settings.py文件,在文件最底部,配置静态文件查找路径

DEBUG = True
...
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

5)在templates/app1/目录下创建json1.html,代码如下:

<html>
<head>
    <title>json</title>
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <script>
        
    $(function () {
        //给btnJson绑定click事件
        $('#btnJson').click(function () {
            //触发事件后发起ajax请求
            $.ajax({                
                'url':'/json2',      //请求地址
                'type':'get',         //指定请求方式
                'dataType':'json',    //期望返回的数据类型
            }).success(function (data) {  //ajax请求成功后会把返回的交给success这个回调函数去处理,data就是请求返回的数据     
                ul = $('#jsonList');    //绑定jsonlist
                ul.append('<li>'+data['h1']+'</li>'); //把获取的数据添加到页面上
                ul.append('<li>'+data['h2']+'</li>');
            })
​
        })
    })
      
    </script>
</head>
<body>
<input type="button" id="btnJson" value="获取json数据">
<ul id="jsonList"></ul>
</body>
</html>

6)运行服务器,在浏览器中输入如下地址。

http://127.0.0.1:8000/json1/

7)点击按钮"获取json数据"后浏览如下图。

ajax代码执行过程如下:

  • 1.发起请求。

  • 2.服务器端视图函数执行。

  • 3.执行回调函数。

5.3、子类HttpResponseRedirect

当一个逻辑处理完成后,不需要向客户端呈现数据,而是转回到其它页面,如添加成功、修改成功、删除成功后显示数据列表,而数据的列表视图已经开发完成,此时不需要重新编写列表的代码,而是转到这个视图就可以,此时就需要模拟一个用户请求的效果,从一个视图转到另外一个视图,就称为重定向。

Django中提供了HttpResponseRedirect对象实现重定向功能,这个类继承自HttpResponse,被定义在django.http模块中,返回的状态码为302。

示例

1)在app1/views.py文件中定义视图red1,代码如下:

from django.http import HttpResponseRedirect
...
# 定义重定义向视图,转向首页
def red1(request):
    return HttpResponseRedirect('/')

2)在app1/urls.py文件中配置url。

    url(r'^red1/$', views.red1),

3)在地址栏中输入网址如下:

http://127.0.0.1:8000/red1/

4)回车后,浏览器地址栏如下图。

重定向简写函数redirect

在django.shortcuts模块中为重定向类提供了简写函数redirect。

1)修改app1/views.py文件中red1视图,代码如下:

from django.shortcuts import render,redirect
...
def red1(request):
    return redirect('/')

6. 普通登录案例

url 视图 模板文件
/login login login.html

1) 显示出登录页面

a) 设计url,通过浏览器访问 http://127.0.0.1:8000/login 时显示登录页面

url(r'^login$',login)

b) 设计url对应的视图函数login。

def login(request):
    return render(request,'app1/login.html')

c) 编写模板文件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="user"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登陆">
</form>
</body>
</html>

2) 登录校验功能

a) 设计url,点击登录页的登录按钮发起请求

http://127.0.0.1:8000/login_check

url(r'login_check$',login_check),

b) 设计url对应的视图函数login_check。

def login_check(request):
    dic = {'python': '123456'}
    user = request.POST.get('user')
    password = request.POST.get('password')
    print(user)
    print(password)
    if dic.get(user)==password:
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/login')

接收表单提交过来的数据。

进行登录校验,若用户名密码正确则跳转到登录成功页。若失败在跳转到登录页面。

c) 登录成功后跳转到首页。

7. 状态保持

http请求是无状态的。无状态指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。无状态的应用层面的原因是:浏览器和服务器之间的通信都遵守HTTP协议。根本原因是:浏览器与服务器是使用Socket套接字进行通信的,服务器将请求结果返回给浏览器之后,会关闭当前的Socket连接,而且服务器也会在处理页面完毕之后销毁页面对象

有时需要保存下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等。 实现状态保持主要有两种方式:

  • 在客户端存储信息使用Cookie。

  • 在服务器端存储信息使用Session。

7.1 Cookie

cookie是由服务器生成,存储在浏览器端的一小段文本信息。

cookie的特点:

1) 以键值对方式进行存储。

2) 通过浏览器访问一个网站时,会将浏览器存储的跟网站相关的所有cookie信息发送给该网站的服务器。request.COOKIES

3) cookie是基于域名安全的。www.baidu.com www.tudou.com

4) cookie是有过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。

设置Cookie

1)打开app1/views.py文件,创建视图cookie_set。

#不设置过期时间
def cookie_set(request):
    response = HttpResponse("<h1>设置Cookie,请查看响应报文头</h1>")
    response.set_cookie('h1', '9999')
    return response
​
# 设置过期时间为了14天
def cookie_set(request):
    response = HttpResponse("<h1>设置Cookie,请查看响应报文头</h1>")
    from datatime import *  #导入日期模块
    d_time=datetime.now()+timedelta(days=14) #获取当前时间 再加上14天
    response.set_cookie('h1', '9999', expires=d_tim) 
    

2)打开app1/urls.py文件,配置url。

    url(r'^cookie_set/$',views.cookie_set),

3)在浏览器输入如下网址。

http://127.0.0.1:8000/cookie_set/

在"开发者工具"中可以在响应头中查看到设置的Cookie信息。

读取Cookie

Cookie信息被包含在请求头中,使用request对象的COOKIES属性访问。

1)打开views.py文件,创建视图cookie_get。

def cookie_get(request):
    str1 = '<h1>读取cookie数据,数据如下:</h1><br>{}'.format(request.COOKIES)
    return HttpResponse(str1)

2)打开urls.py文件,配置url。

    url(r'^cookie_get/$',views.cookie_get),

3)在浏览器输入如下网址。

http://127.0.0.1:8000/cookie_get/

4)打开“开发者工具”,在请求头中可以查看Cookie信息,浏览效果如下图:

7.2、Session

session存储在服务器端。

session的特点:

1) session是以键值对进行存储的。

2) session依赖于cookie。唯一的标识码保存在sessionid cookie中。

3) session也是有过期时间,如果不指定,默认两周就会过期。

启用Session

Django项目默认启用Session。

打开settings.py文件,在项MIDDLEWARE_CLASSES中启用Session中间件。

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',  #默认启用的
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

禁用Session:将Session中间件删除。

存储方式

打开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应用。

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions', # 默认注册好了
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app1',
)

5)迁移后会在数据库中创建出存储Session的表。

mysql> show tables;
+----------------------------+
| Tables_in_demo3            |
+----------------------------+
| app1_newsinfo              |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.00 sec)

6)表结构如下图。

mysql> desc django_session;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| session_key  | varchar(40) | NO   | PRI | NULL    |       |
| session_data | longtext    | NO   |     | NULL    |       |
| expire_date  | datetime(6) | NO   | MUL | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

由表结构可知,操作Session包括三个数据:键,值,过期时间。

依赖于Cookie

所有请求者的Session都会存储在服务器中,服务器如何区分请求者和Session数据的对应关系呢?

答:在使用Session后,会在Cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid后,会根据这个值找出这个请求者的Session。

结果:如果想使用Session,浏览器必须支持Cookie,否则就无法使用Session了。

存储Session时,键与Cookie中的sessionid相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置。

对象及方法

通过HttpRequest对象的session属性进行会话的读写操作。

1) 以键值对的格式写session。

request.session['键']=值

2)根据键读取值。

request.session.get('键',默认值)

3)清除所有session,在存储中删除值部分。

request.session.clear()

4)清除session数据,在存储中删除session的整条数据。

request.session.flush()

5)删除session中的指定键及值,在存储中只删除某个键及对应的值。

del request.session['键']

6)设置会话的超时时间,如果没有指定过期时间则两个星期后过期。

request.session.set_expiry(value)
  • 如果value是一个整数,会话将在value秒没有活动后过期。

  • 如果value为0,那么用户会话的session将在用户的浏览器关闭时过期。

  • 如果value为None,那么会话永不过期。

示例

写session

1)打开app1/views.py文件,创建视图session_set,代码如下:

def sesion_set(request):
    request.session['num']=10000
    return HttpResponse('把num写入session中')

2)打开app1/urls.py文件,配置url。

    url(r'^session_set/$',views.session_set),

3)运行服务器,打开浏览器请求如下网址。

http://127.0.0.1:8000/session_set/

4)浏览效果如下图,在"开发者工具"中可以查看到响应头中创建了Cookie,里面有个键为sessionid。

5)打开MySQL数据库命令行,查询数据如下图。

查看Cookie中的sessionid=so7equxdjkpkwvanyko8hkuo8hjtrlao",数据表中session的键为“so7equxdjkpkwvanyko8hkuo8hjtrlao”,是一样的,这样,服务器就可以在众多的请求者中找到对应的Session数据。

在MySQL数据库命令行中复制值,在Base64解码中进行解码查看如下图。

读session

1)打开views.py文件,创建session_get视图如下:

def session_get(request):
    h1=request.session.get('num')
    return HttpResponse(num)

2) 配置url

url(r'^session_get',session_get),

2)刷新浏览器效果如下图。

删除

1)打开views.py文件,修改session_del视图如下:

def session_del(request):
    del request.session['h1']
    return HttpResponse('ok')

2)刷新浏览器,在数据库命令行中查询,base64解码后如下图。

如果将所有的键及值都删除,逐个调用del太麻烦,可以使用clear()方法。

删除session

1)打开views.py文件,修改session_del视图如下:

def session_test(request):
    # del request.session['h1']
    request.session.flush()
    return HttpResponse('ok')

2)刷新浏览器,在数据库命令行中查询如下图。

使用Redis存储Session

会话还支持文件、cookie、Memcached、Redis等方式存储,下面演示使用redis存储。

1)安装包。

pip install django-redis-sessions==0.5.6

2)修改settings文件,增加如下项:

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 10
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'

3)浏览器访问127.0.0.1:8000/session_set

4)管理redis的命令,需要保证redis服务被开启。

查看:ps ajx|grep redis
启动:sudo service redis start
停止:sudo service redis stop
使用客户端连接服务器:redis-cli
切换数据库:select 2
查看所有的键:keys *
获取指定键的值:get name

5)刷新浏览器,在redis客户端中查看数据如下。

(dj_py3) sxt@ubuntu:~$ redis-cli
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> keys *
1) "session:ocxh9z953rcjw3e67zs6jja1q2ccskbd"
127.0.0.1:6379[2]> get session:ocxh9z953rcjw3e67zs6jja1q2ccskbd
"YzgzMTVhYjM5ODZiMjY2MGNjODE3YTc3MDk5M2U3NDczN2E1NjI5NTp7Im51bSI6MTAwMDB9"
127.0.0.1:6379[2]> exit
​

8、作业

1、利用ajax实现登录,登录成功跳转到登录页面,失败给出相应提示

2、利用session实现保持登录状态

猜你喜欢

转载自blog.csdn.net/hard_days/article/details/88384498
今日推荐