六、视图层(二)

一、三天免登陆

#### 创建templates/login.html
```
<form action="/student/login/" method="post">
        {% csrf_token %}
        <table>
            <tr>
                <td>用户名:</td>
                <td>
                    <input type="text" name="sname" value="{{ sname }}"/>
                </td>
            </tr>
            <tr>
                <td>密码:</td>
                <td>
                    <input type="password" name="spwd" value="{{ spwd }}"/>
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="checkbox" name="flag" value="1" checked />记住密码
                </td>
            </tr>
            <tr align="center">
                <td colspan="2">
                    <input type="submit" value="登录"/>
                </td>
            </tr>
        </table>
    </form>
```

#### 配置路由
- test15/urls.py
```
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^student/', include('stu1.urls')),
]

```
- stu1/urls.py
```
#coding=utf-8
from django.conf.urls import url
import views
urlpatterns=[
    url(r'^login/$',views.login_view),
]
```
#### 创建视图函数
- stu1/views.py
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def login_view(request):
    if request.method == 'GET':
        #判断request中是否存在'login'对应cookie信息
        if request.COOKIES.has_key('login'):
            #'zhangsan,123'
            login = request.COOKIES.get('login','').split(',')
            sname = login[0]
            spwd = login[1]
            return render(request,'login.html',{'sname':sname,'spwd':spwd})
        return render(request,'login.html')
    else:
        #获取请求参数
        sname = request.POST.get('sname')
        spwd = request.POST.get('spwd')
        flag = request.POST.get('flag')
        response = HttpResponse()
        #判断是否登录成功
        if sname=='zhangsan' and spwd=='123':
            response.content = '登录成功!'
            #判断是否需要记住密码
            if flag:
                #将用户名和密码存放至cookie中('zhangsan,123')
                response.set_cookie('login',sname+','+spwd,max_age=3*24*60*60,path='/student/login/')
            else:
                #当不需要记住密码时,需要删除cookie中‘login’对应的数据
                response.delete_cookie('login',path='/student/login/')
        else:
            #当登录失败时,需要删除cookie中‘login’对应的数据
            response.delete_cookie('login', path='/student/login/')
            #重定向
            response.status_code = 302
            response.setdefault('Location','/student/login/')
 
        return response

```

#### 访问路径
```
http://127.0.0.1:8000/student/login/
```
二、Session
1. cookie引入session:
    cookie看似解决了HTTP(短连接、无状态)的会话保持问题,但把全部用户数据保存在客户端,存在安全隐患。
2. cookie+session
    把关于用户的数据保存在服务端,在客户端cookie里加一个sessionID(随机字符串)
    基于以上原因:cook+session组合就此作古了单单使用cookie做会话保持的方式;
3. cookie+session的工作流程:
    (1)、当用户来访问服务端时,服务端生成一个随机字符串;
    (2)、当用户登录成功后 把 {sessionID :随机字符串} 组织成键值对 加到 cookie里发送给用户;
    (3)、服务器以发送给客户端 cookie中的随机字符串做键,用户信息做值,保存用户信息;
 

4. 保存在服务端session数据格式
    session_key    SessionStore() 
        {
       
         session_key                                       数据字典
       
        sessionid1:                     {id:1,nam:"alex",account:1000000000 },
       
        sessionid2:                     {id:1,nam:"eric",account:10}
       
        }
 
 

#### Session中存储值
```
def session_view(request):
    # SessionStore()
    #设置session数据
    # request.session['user']='zhangsan'
    #设置过期时间(单位秒)
    # request.session.set_expiry(10*60)
    #删除当前user对应的session数据
    # del request.session['user']
    #删除所有session数据(不清空数据库,只删除cookie中的sessionid)
    # request.session.clear()
    #清空数据库中的session数据
    # request.session.flush()
    #获取sessionid
    # print request.session.session_key
    return HttpResponse('保存成功!')
```

#### Session中取值
```
def getsession_view(request):
    #session中取值
    user = request.session['user']
    # user = request.session.get('user')
    return HttpResponse('datas:%s'%user)

```

#### Session存储引擎

```
#settings.py文件中
    #Session默认存储在数据库
 SESSION_ENGINE = 'django.contrib.sessions.backends.db'
    #内存
 SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
 # 可以存储自定义对象,内存不用json序列化
 # 服务器重启,数据丢失
 
    #内存+数据库(双缓存)
 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' 
 # 内存速度快,数据库慢
 # 储存的步骤,先存到内存,在存到数据库
 # 先从内存读,再从数据库读,如果从数据库读到了,再放入内存
    #file
  
  SESSION_ENGINE = 'django.contrib.sessions.backends.file'
  SESSION_FILE_PATH = os.getcwd()
   
    #signed_cookies
 SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
 # 将数据加密,存到cookie中了(存到浏览器)
```
 三、session实现用户信息的保存
#### 配置URL
```
#coding=utf-8
from django.conf.urls import url
import views
urlpatterns=[
    url(r'^sessionlogin/$',views.sessionlogin_view),
    url(r'^usercenter/$',views.center_view),
]
```
 

#### 创建视图函数
```
class User(object):
    def __init__(self,uname,pwd):
        self.uname = uname
        self.pwd = pwd

import jsonpickle
def sessionlogin_view(request):
    uname = request.GET.get('uname','')
    pwd = request.GET.get('pwd','')
    if uname=='zhangsan' and pwd=='123':
        user = User(uname,pwd)
        request.session['user'] = jsonpickle.dumps(user)
        return HttpResponseRedirect('/student/usercenter/')
    return HttpResponse('登录失败')

def center_view(request):
    user = jsonpickle.loads(request.session['user'])
    return HttpResponse('欢迎%s登录成功!'%user.uname)
```
 四、jsonpickle实现序列化和反序列化
 
 
```
#coding=utf-8
from django.http import HttpResponse
from django.views import View
import jsonpickle
class User(object):
    def __init__(self,uname,pwd):
        self.uname = uname
        self.pwd = pwd
 
class IndexView(View):
    def get(self,request,*args,**kwargs):
        uname = request.GET.get('uname','')
        pwd = request.GET.get('pwd','')
        if uname=='zhangsan' and pwd=='123':
            user = User(uname,pwd)
            #{"py/object": "demo5.views.User", "uname": "zhangsan", "pwd": "123"}
            # ustr = jsonpickle.encode(user)
            # {"py/object": "demo5.views.User", "uname": "zhangsan", "pwd": "123"}
            ustr =jsonpickle.dumps(user)
            print ustr
            request.session['user'] = ustr
        return HttpResponse('Get请求')
 
 
class GetSession(View):
    def get(self,request,*args,**kwargs):
        user = request.session.get('user','')
        # <demo5.views.User object at 0x0000000003D48588>
        # uuser = jsonpickle.decode(user)
        # <demo5.views.User object at 0x0000000003D1A0F0>
        uuser = jsonpickle.loads(user)
        print uuser
        return HttpResponse('User:%s'%uuser.uname)

```
 
#### 序列化部分字段
```
class User(object):
    def __init__(self,uname,pwd):
        self.uname = uname
        self.pwd = pwd
    def __getstate__(self):
        data = self.__dict__.copy()
        del data['pwd']
        return data

u = User('zhangsan','123')      
s = jsonpickle.encode(u,unpicklable=False)
# jsonpickle.dumps(u,unpicklable=False)
print s
#{"uname": "zhangsan"}

```
原文地址:https://www.cnblogs.com/dangjingwei/p/12906035.html