Django学习记录之——cookie session

 

目录

cookie和session

cookie使用

cookie使用案例:实现一个简单登陆功能

用户登陆状态保存

定向到用户登陆之前访问的页面

设置cookie超时参数

注销

session基本使用

session版本的登陆



cookie和session

cookie和session

    - cookie
        - 服务端保存在客户浏览器上的信息都可以称为cookie
        - cookie的表现形式是以键值对的形式,可以有很多对
        - 作用是网站用来辨别用户身份

    - session
        - session是存储在服务端上的信息
        - session的表现形式也是键值对

    - 总结
        - cookie就是保存在客户端上的信息
        - session就是保存在服务端上的信息
        - session是基于cookie工作的(大部分的保存用户状态的操作都需要用到cookie)

cookie使用

cookie操作

    - 尽管cookie是服务端告诉客户端浏览器需要保存内容,但是客户端浏览器也可以选择拒绝保存,
      如果禁止了只要是需要记录用户状态的网站登录功能都无法使用了

    - django中cookie的设置
        - set_cookie()
        - 在视图函数中,要返回一个HttpResponse对象,render,redirect的本质也是返回HttpResponse对象
        - 如果我们要设置cookie,必须要先实例化一个对象,再给这个对象设置cookie
        - 例如:
            http_response_obj = HttpResponse()
            http_response_obj.set_cookie(key, value)
            return http_response_obj

    - django获取cookie
        - request.COOKIES


    - cookie的其他操作
        - 设置超时时间
            - max_age
            - expires 用于IE浏览器
            http_response_obj.set_cookie(key, value, max_age=5, expires=5)
            - 超过该时长cookie失效
            - max_age和expires单位是秒
        
        - 主动删除cookie
            - http_response_obj.delete_cookie(key)
            - 注销功能

cookie使用案例:实现一个简单登陆功能

    - 用cookie来保存用户的登陆状态

    - 在用户访问需要登陆的页面的时候,先定位到登陆页面,登陆成功后返回当前页面

    - 注销

用户登陆状态保存

1. 登陆页面的视图函数及视图

def login(request):
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'wcy' and password == '123456':
            return redirect('/home/')
    return render(request, 'login.html')
<form action="" method="post">
    <p>账号:<input type="text" name="username"></p>
    <p>密码:<input type="text" name="password"></p>
    <input type="submit">
</form

 2.登陆成功后默认返回一个home页面

def home(request):
    return HttpResponse('home页面,登陆成功默认跳转的页面')

可以发现一个问题,当我们登陆成功后会跳转到home页面,但是如果直接访问home页面也能够直接访问,不符合我们的登陆逻辑,那么接下来就要使用cookie来保存用户的登陆信息。

要使用cookie,我们就要先实例化对象,然后使用对象来添加cookie,接下来将我们的登陆的视图函数改成如下:

def login(request):
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'wcy' and password == '123456':
            http_response_obj = redirect('/home/')  # 实例化
            http_response_obj.set_cookie('is_login', 'yes')  # 添加cookie
            return http_response_obj
    return render(request, 'login.html')

此时登陆后我们查看页面的cookie会发现我们添加的cookie存在,但是我们只是添加了cookie,并没有使用它,接下来我们去home函数中判读cookie. 

home函数中的判断如下:

当cookie验证成功时进入home页面,否则继续返回登陆页面

def home(request):
    if request.COOKIES.get('is_login') == 'yes':
        return HttpResponse('home页面,登陆成功默认跳转的页面')
    return redirect('/login/')

至此,我们实现了登陆单个页面的cookie功能,我们需要在页面中判断cookie是否正确,那么当我们有许多个页面需要登陆才能访问呢?我们难道也要在对应的视图函数里一个一个的判断cookie吗,显然是吃力不讨好的,那么我们就可以写一个装饰器来判断cookie,这样只需要使用装饰器判断即可。

首先我们再添加几个页面

def page_a(request):
    return HttpResponse('a页面,登陆成功才能访问的页面')


def page_b(request):
    return HttpResponse('b页面,登陆成功才能访问的页面')


def page_c(request):
    return HttpResponse('c页面,登陆成功才能访问的页面')

 然后我们写一个函数装饰器来判断cookie

def login_auth(func):
    """
    登陆状态判断
    """
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('is_login') == 'yes':   
            res = func(request, *args, **kwargs)
            return res
        else:
            return redirect('/login/')
    return inner

然后只需要放在各个视图函数之前即可

@login_auth
def home(request):
    # if request.COOKIES.get('is_login') == 'yes':
    #     return HttpResponse('home页面,登陆成功默认跳转的页面')
    # return redirect('/login/')
    return HttpResponse('home页面,登陆成功默认跳转的页面')


@login_auth
def page_a(request):
    return HttpResponse('a页面,登陆成功才能访问的页面')


@login_auth
def page_b(request):
    return HttpResponse('b页面,登陆成功才能访问的页面')


@login_auth
def page_c(request):
    return HttpResponse('c页面,登陆成功才能访问的页面')

此时如果没有登录,访问上述页面都会定向到登陆页面,登陆成功之后才可以继续访问需要登陆的页面。

不过此时又有一个问题,当我们访问一个需要登陆的页面被重定向到登陆页面后,登陆成功后会自动的跳转到home页面而不是之前我们想要访问的页面,这是非常的不人性化的,所一接下来来解决这个问题。

定向到用户登陆之前访问的页面

首先我们要保存用户想访问的页面,登陆成功后再定向到之前访问的页面即可,我们需要在装饰器函数中更改逻辑。

首先将用户访问的页面地址保存,然后用next参数添加到定向的login页面后面

def login_auth(func):
    """
    登陆状态判断
    """
    def inner(request, *args, **kwargs):
        user_visit_page = request.get_full_path()  # 获取用户的访问地址
        if request.COOKIES.get('is_login') == 'yes':
            res = func(request, *args, **kwargs)
            return res
        else:
            # 没有登陆时 定向到登陆页面 同时记录用户的访问地址
            # 在login后加上一个参数next,记录用户的访问地址,然后在login函数中获取,再判断
            return redirect('/login/?next={}'.format(user_visit_page))
    return inner

然后在login函数中获取next中的值,登陆成功后重定向到用户最开始访问的页面

def login(request):
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'wcy' and password == '123456':
            # 登陆成功后获取用户的访问地址,地址是存在next参数中
            user_visit_url = request.GET.get('next')
            if user_visit_url:
                # 如果存在就定向到用户刚开始访问的这个地址
                http_response_obj = redirect(user_visit_url)
            else:
                http_response_obj = redirect('/home/')  # 实例化
            http_response_obj.set_cookie('is_login', 'yes')  # 添加cookie 无论定向到哪都要加cookie
            return http_response_obj
    return render(request, 'login.html')

 最后实现了该功能

设置cookie超时参数

当用户长时间不登陆网站时,需要重新登陆,那么我们就可以设置一个超时时间,当超过这个时间后cookie会失效,用户需要重新登陆。

超时参数的设置非常简单,只要在set_cookie中添加一个参数max_age即可

# 添加cookie 无论定向到哪都要加cookie
# 5s后cookie失效
http_response_obj.set_cookie('is_login', 'yes', max_age=5)  

IE浏览器中max_age要替换成expires参数才会生效

注销

注销只需要删除cookie即可

定义视图函数

@login_auth
def logout(request):
    # 登陆成功才能注销,所以也要加装饰器判断
    http_response_obj = redirect('/login/')
    http_response_obj.delete_cookie('is_login')
    return http_response_obj

然后登陆成功后访问logout页面即可注销,这里就不加按钮功能了

cookie的基本使用到此结束


session基本使用

session操作

    - session数据是保存在服务端的,给客户返回的是一个随机字符串
      格式:  sessionid:随机字符串
    - session数据在服务端是默认保存早数据库中的,可以指定其他的存储方法
        - 默认情况下操作session需要用到django创建的表django_session
        - 首先要执行数据库的迁移命令,创建默认的django_session表

    - 设置session
        request.session[key] = value
        - 内部实现步骤
            - django会自动生成随机字符串
            - django自动将随机字符串存储到django_session表中
                - 现在内存中产生操作数据的缓存
                - 在相应结果的django中间件的时候才会真正的操作数据库
            - 将产生的随机字符串发送给客户端浏览器保存
    - 获取session
        request.session.get(key)
            - 内部实现步骤
                - 从浏览器请求中获取sessionid对应的随机字符串
                - 将获取到的随机字符串去django_session表中去比对
                    - 如果比对成功,则返回对应的数据并且封装到request.session中
                    - 如果比对失败,则request.session.get(key)返回的是None

    - django中session默认的失效时间是14天,可以人为修改

    - django_session表中的数据条数是取决于浏览器的
        - 同一个计算机上同一个浏览器只会有一条记录
        - 同一台计算机不同的浏览器也会有新的数据
        - 当session过期的时候,同一台计算机同一个浏览器也肯有多条数据

    - session的其他操作
        - session可以当做字典来操作
        - 批量添加session
            - request.session[key1] = value1
            - request.session[key2] = value2
            - request.session[key4] = value3
            - 上面已经说过,同一浏览器只有一条记录,所以无论添加多少条session,
              表中都只有一条数据,但是我们可以获取到我们设置的所有session

        - session设置过期时间
            - request.session.set_expiry()
            - 括号里可以放四种对象
                - 整数:秒
                - 日期对象:到期时间
                - 0:关闭浏览器默认失效
                - 不写:取决于django的全局session默认过期时间,默认是14天
            - 读session的时候不会修改session的有效期,修改session的时候会重新设置session的有效期,会从修改的时间,重新计时。
        
        - 清除session
            - request.session.delete()  # 只删服务端
            - request.session.flush()   # 浏览器和服务端全部清空

session版本的登陆

session版本的登陆和cookie版本的逻辑大致相同,只是将cookie的使用改成了session的使用

在使用session之前一定要记得数据库迁移命令,生成django_session表

视图函数部分

from django.shortcuts import render, HttpResponse, redirect, reverse
# Create your views here.


def login_auth(func):
    """
    登陆状态判断
    """
    def inner(request, *args, **kwargs):
        user_visit_page = request.get_full_path()  # 获取用户的访问地址
        # print(request.session.get('is_login'))
        if request.session.get('is_login') == 'yes':
            res = func(request, *args, **kwargs)
            return res
        else:
            # 没有登陆时 定向到登陆页面 同时记录用户的访问地址
            # 在login后加上一个参数next,记录用户的访问地址,然后在login函数中获取,再判断
            return redirect(reverse('login')+'?next={}'.format(user_visit_page))
    return inner


def login(request):
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'wcy' and password == '123456':
            user_visit_url = request.GET.get('next')
            # 添加session
            request.session['is_login'] = 'yes'
            request.session['哈哈哈'] = '我来了'
            request.session.set_expiry(1000)  # 设置到期时间
            # 判断用户之前访问的页面,登陆成功后定向到该页面
            if user_visit_url:
                return redirect(user_visit_url)
            else:
                return redirect(reverse('home'))  # 反向解析重定向
    return render(request, 'login_session.html')


@login_auth
def home(request):
    return HttpResponse('home页面,登陆成功默认跳转的页面')


@login_auth
def page_a(request):
    return HttpResponse('a页面,登陆成功才能访问的页面')


@login_auth
def page_b(request):
    return HttpResponse('b页面,登陆成功才能访问的页面')


@login_auth
def logout(request):
    # 登陆成功才能注销,所以也要加装饰器判断
    # 清除客户端和服务端session信息
    request.session.flush()
    return redirect(reverse('login'))

这里大致和cookie部分相同 

路由部分

# app02 urls
from django.urls import path
from app02 import views

# session模块使用
urlpatterns = [
    path('login/', views.login, name='login'),
    path('home/', views.home, name='home'),
    path('a/', views.page_a),
    path('b/', views.page_b),
    path('logout/', views.logout),
]

通过name来实现反向解析

功能和cookie部分完全一样

cookie和session的基本使用就到此结束啦

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值