一 . Cookie
1.cookie 是什么?
保存在浏览器端的键值对!
服务端在返回响应的时候,告诉浏览器保存的键值对!浏览器可以拒绝保存Cookie.
2. 为什么要有cookie?
HTTP请求是无状态的,我们需要保存状态 --> cookie
3. Django中cookie的使用
1. 设置cookie
rep = HttpResponse("ok")
rep.set_cookie("key", "value", max_age=xx秒)
rep.set_signed_cookie("key", "value", salt="ooxx", max_age=xx秒)
2. 获取cookie
request.COOKIES.get("key")
request.get_signed_cookie("key", default="", salt="ooxx")
参数:
- default: 默认值
- salt: 加密盐
- max_age: 后台控制过期时间
4. cookie有失效时间
1. Django中不设置,关闭浏览器就失效了
2. 通过max_age设置超时时间
5. 补充3点:
1. 如何登陆后再跳转回之前访问的页面
写个登录函数:例子
1 def login(request):
2 if request.method == "POST":
3 path = request.GET.get("path")
4 print(path)
5 username = request.POST.get("username")
6 pwd = request.POST.get("pwd")
7 if username == "alex" and pwd == "123":
8 if path:
9 rep = redirect(path)
10 else:
11 rep = redirect("/publisher_list/")
12 rep.set_signed_cookie("hu", "hao", salt="ooxx", max_age=7)
13 return rep
14 else:
15 return HttpResponse("用户名或者密码错误")
16 else:
17
18 return render(request, "login.html")
写个装饰器
from functools import wraps
# 装饰器版本登录认证
def login_check(func):
@wraps(func)
def inner(request, *args, **kwargs):
path = request.path_info
# 登录验证
v = request.get_signed_cookie("hu", default="", salt="ooxx") # 获取加盐的cookie
if v == "hao":
return func(request, *args, **kwargs)
else:
return redirect("/login/?path={}".format(path))
return inner
你想要访问那个页面,把装饰器加到它的上面
@login_check
def book_list(request):
data = models.Book.objects.all()
return render(request, "book_list.html", {"book_list": data})
最后访问,book_list这个页面,会让你先登录,并且在url后面拼接一个目录
http://127.0.0.1:8001/login/?path=/book_list/,然后登陆成功,跳转到book_list
注意:login.html文件里面的action一定要写空,否则不能跳转,或者写成{{request.get_path_info}}
2. 如何将FBV的装饰器应用到CBV上?
在views里面导入
from django.utils.decorators import method_decorator
就是
@method_decorator(login_check) 括号里面是你写的装饰器函数
例子:
class AddBook(views.View):
@method_decorator(login_check) # login_check是刚才写的装饰器函数
def get(self, request):
data = models.Publisher.objects.all()
return render(request, "add_book.html", {"publisher_list": data})
def post(self, request):
book_name = request.POST.get("title")
publisher_id = request.POST.get("publisher")
publisher_obj = models.Publisher.objects.get(id=publisher_id)
# 创建书籍
models.Book.objects.create(
title=book_name,
publisher_id=publisher_id
# publisher=publisher_obj
)
return redirect("/book_list/")
3. 装饰器修复技术 --> from functools import wraps
在inner函数的上面加上@wraps(func),默认不加是不影响使用的,只是被装饰的函数名字和注释信息都不能查看了
例子:
from functools import wraps
def wrapper(func):
@wraps(func) # 借助内置的工具修复被装饰的函数
def inner(*args, **kwargs):
print("呵呵")
func(*args, **kwargs)
return inner
@wrapper
def foo(arg):
"""
这是一个测试装饰器的函数
:param arg: int 必须是int类型
:return: None
"""
print("嘿嘿嘿" * arg)
foo(10)
print(foo.__doc__)
二 session
为什么要有session
1. Cookied额缺点:
1. 数据量只有4096
2. 数据都保存在客户端(浏览器)上,不安全
2. Session
保存在服务端的键值对
1. 请求来了之后,还是生成随机字符串
2. 以随机字符串为key,在服务端生成一个大字典,真正保存数据是value
3. 把随机字符串以cookie的形式回复给浏览器
4. 下一次请求再来的时候,会携带上一步的随机字符串
5. 从请求中拿到随机字符串,
6. 去后端以 该随机字符串为key找对应的value
7. value里面存的就是真正有用的数据
3. Django中如何使用Session
1. 无论设置Session还是获取Session都是针对request对象来操作
2. 设置Session
request.session["key"] = "value"
3. 获取session
request.session.get("key")
4. 其他常用命令
1. # 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
2. # 删除当前的会话数据并删除会话的Cookie。
request.session.flush()
3. 设置超时时间
request.session.set_expiry(7)
5. 常用配置项(写在Settings.py中)
# 全局配置session超时时间
SESSION_COOKIE_AGE = 60 * 60 * 24 * 2 #7天
# 是否每次请求都刷新session超时时间
SESSION_SAVE_EVERY_REQUEST = True
例子:
def login_check(func):
@wraps(func)
def inner(request, *args, **kwargs):
next = request.path_info
# 登录验证
# 取Session
v = request.session.get("s21")
if v == "hao":
return func(request, *args, **kwargs)
else:
return redirect("/login/?next={}".format(next))
return inner
# 登录 session验证
def login(request):
if request.method == "POST":
next = request.GET.get("next")
username = request.POST.get("username")
pwd = request.POST.get("pwd")
if username == "alex" and pwd == "123":
if next:
rep = redirect(next)
else:
rep = redirect("/secode/")
request.session["s21"] = "hao"
request.session.set_expiry(70)
return rep
else:
return HttpResponse("走吧")
else:
return render(request, "login.html")
@login_check
def index(request):
return render(request, "index.html")
@login_check
def secode(request):
return render(request, "secode.html")