文章目录

  • 对比
  • cookie
  • 基本操作
  • 实例
  • Session
  • 原理
  • 设置 session
  • 获取 session
  • session 常用方法
  • 实例



对比

  • cookie 是保存在浏览器的一组键值对, 相当于本机使用
  • session 是保存在服务器端的一组键值对
  • 数据更为安全
  • 可以存储的数据量比 cookie 大
  • 依赖 cookie 完成

cookie

基本操作

# 设置 cookie

# 获取 response 对象
rep = redirect("/host_list/")
# 明文 cookie
# max_age: 单位是秒, 指定为 0 关闭浏览器即失效
# expires: 指定过期时间 还支持是一个 datetime 或 timedelta ,可以指定一个具体日期时间, 指定为 None 为永不过期
rep.set_coookie("key", "value", ..)

# 加盐 cookie, salt 为盐
rep.set_signed_cookie("key", "value", salt="salt_word", max_age=0)

##################

# 获取 cookie

# 取明文 cookie
request.COOKIES.get("key")

# 取加盐 cookie, default 不写会报错
request.get_signed_cookie("key", default="", salt="salt_word")

实例

from functools import wraps # 修复装饰器
from django.utils.decorators import method_decorator # 类装饰需要

def login_check(func):
	"""
	登录校验装饰器
	如果cookie 验证成功, 表示已经登录, 则正常执行代码
	如果cookie 验证失败, 表示没有登录, 显示登录页面, 并设置登录成功后, 显示原页面
	"""
	@wraps(func) # 完美修复装饰器的问题, 可查看原函数的所有内容
    def inner(request, *args, **kwargs):
        v = request.COOKIES.get("s21")
        if v == "hao":
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next={}".format(request.path_info)) # 根据原 url 拼接出新 url
    return inner


# FBV 可以直接使用装饰器
@login_check
def book_list(request):
    return HttpResponse("book_list")


class BookAdd(views.View):
	# CBV 需要添加模块
    @method_decorator(login_check)
    def get(self, request):
        return HttpResponse("book_add_get")

    def post(self, request):
        return HttpResponse("book_add_post")

Session

原理

1. 请求来了之后, 生成随机字符串
2. 以随机字符串为 key, 在服务端生成一个大字典, 保存的数据为 value
3. 把随机字符串以 cookie 的形式回给浏览器
4. 下次请求时, 会携带上次的随机字符串
5. 从请求中取随机字符串
6. 去后端以该随机字符串为 key 找对应的 value

设置 session

# session 是对 request 进行操作, django 会对 session 进行自动加密
request.session["s21"] = "hao"

获取 session

# 同 cookie
request.session.get("s21")

session 常用方法

request.session["k1"] = 123 # 设置 session

request.session.get["k1"] # 取 session

request.session.setdefault("k1",123) # 存在则不设置

del request.session["k1"]

request. session.clear_expired() # 删除失效日期小于当前日期的 session

request.session.flush() # 用于注销

request.session.set_expiry(v) # 给 session 设置超时时间
"""
1. v 为整数, 则为秒
2. v 为 datetime 或 timedelta, session 会根据时间失效
3. v 为 0, 关闭浏览器就失效
4. v 为 None, session 会依赖全局 session 策略

"""

# settings.py中添加
SESSION_COOKIE_AGE = 60*60*24*2 # 全局超时时间设置
SESSION_SAVE_EVERY_REQUEST = True # 每次请求刷新超时时间

实例

from django.shortcuts import render, redirect, HttpResponse
from django import views

# Create your views here.


def check_login(func):
    def inner(request, *args, **kwargs):
        # 获取 session
        v = request.session.get("s21")
        if v == "hao":
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next={}".format(request.path_info))
    return inner


class Login(views.View):
    def get(self, request):
        return render(request, "login.html")

    def post(self, request):
        # 设置 session
        request.session["s21"] = "hao" # 通过 request 进行设置
        request.session.set_expiry(7) # 设置 7s 的超时时间
        return redirect("/index/")


@check_login
def index(request):
    return render(request, "index.html")


def logout(request):
    request.session.flush()
    return redirect("/login/")