django操作cookie和session补充、CBV添加装饰器 Django自定义中间件执行顺序

昨日内容回顾

  • 批量插入数据
# 本质就是一次插入多条数据,执行一次SQL语句

# mysql连接池
ORM:
    l = []
    for i in range(10000):
        res = models.Book('')
        l.append(res)
    models.Book.objects.bulk_create(l)
faker模块
pip install faker
from faker import Faker
faker = Faker()
fake.name()
  • 分页原理
1. 每页展示多少条数据: 10
2. 总共有多少条数据: 99
3. 当前页:?page=2
select * from t  limit 990, 10
  • cookie与session介绍
# 理论
cookie:
	1. 数据存储在客户端(浏览器)
	2. 原理:
		后端把用户的数据保存在浏览器,当用户再次访问的时候,会携带着用户信息提交到后端,后端在做验证
	3. cookie最大的问题就是不安全
	4. 不占用后端资源
    
session:
	1. 数据存储到服务端
		1.1 文件
		1.2 数据库
		1.3 redis
	2. 原理:
		'''
		当用户登录成功,会自动生成一个随机字符串,拿随机字符串跟用户信息做对应
		随机字符串:用户信息
		把随机字符串返回给浏览器保存起来,用户在登录的时候,携带着这个cookie信息,后端拿着随机字符串去数据库中查询
		'''
	3. session是基于cookie工作的
	4. 用户可以主动禁止掉cookie的保存
  • django操作cookie
obj = HttpResponse()

return obj
'''
	cookie是有过期时间的,在设置cookie的时候可以设置
'''
设置cookie:
	obj.set_cookie('username', 'aaaa', max_age=120)
    
获取cookie:
	request.COOKIES.get('username')
    
删除cookie:
	obj.delete_cookie('username')
    
注销功能:
	删除cookie达到目的

今日内容概要

  • django操作cookie和session
  • CBV添加装饰器
  • 中间件

内容详细

1. django操作cookie和session

# 1.cookie相关
	以昨日的登录系统为例
	添加判断是否登录的装饰器
	添加注销
    
    
# 在views.py文件中测试:
from django.shortcuts import render, HttpResponse, redirect
from app01 import models

# 登录
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        userinfo = models.Book.objects.filter(username=username, password=password).first()
        if userinfo:
            # 保存用户信息
            obj = HttpResponse('登录成功')
            # 保存数据到cookie
            obj.set_cookie('username', userinfo.username, max_age=120)  # max_age 时间 秒 过时数据自动清空
            obj.set_cookie('id', userinfo.id)
            return obj
    return render(request, 'login.html')


# 公共装饰器
def login_auth(func):
    def index(request, *args, **kwargs):
        # request = args[0]
        if request.COOKIES.get('username'):
            return func(*args, **kwargs)
        else:
            return  redirect('/login/')
    return index


# 判断不登录不让访问
@login_auth
def home(request):
    pass
    # if request.COOKIES.get('username'):
    #     return HttpResponse('已经登录')
    # else:
    #     return redirect('/login/')


# 注销功能
def logout(request):
    obj = redirect('home')
    obj.delete_cookie('username')
    # obj.delete_cookie('id')  # 基于获取的信息判断删除哪一项信息
    return obj
    
# 添加路由:
	url(r'^logout/', views.logout),
    
    
    
# 2.保存用户信息到 session
	默认是保存在 django_session 表中
# 登录
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        userinfo = models.Book.objects.filter(username=username, password=password).first()
        if userinfo:
            # 保存用户信息
            obj = HttpResponse('登录成功')
            # 保存数据到cookie
            # obj.set_cookie('username', userinfo.username, max_age=120)  # max_age 时间 秒 过时数据自动清空
            # obj.set_cookie('id', userinfo.id)

            # 保存数据到session
            request.session['username'] = userinfo.username
            request.session['id'] = userinfo.id
            """
            设置session的过程发生什么事?
                1.自动生成了随机字符串
                2.把用户数据保存到数据库中 并且加密处理
                3.把随机字符串返回给浏览器保存了 并且cookie的key叫 sessionid
            """
            return obj
    return render(request, 'login.html')


# 公共装饰器
def login_auth(func):
    def index(request, *args, **kwargs):
        # request = args[0]
        # if request.COOKIES.get('username'):
        if request.session.get('username'):
            return func(request, *args, **kwargs)
        else:
            return  redirect('/login/')
    return index


# 判断不登录不让访问
@login_auth
def home(request):
    print(request.session.get('username'))
    """
    获取session的过程发生了哪些事?
        1.先获取cookie值(sessionid)
        2.拿着sessionid的值 去数据库中查询数据 如果查询没有 就是没有登录
        3.如果查询到已存在 说明登录了 并且把用户数据反解密 把用户数据封装到了request.session.
            select * from django_session where session_key = request.session.get('username')
        4.以上操作是在 请求来的时候做的 且是在中间件做的
    """
    return HttpResponse('home')


# 清空session
def logout(request):
    request.session.delete()
    request.session.flush()

    return redirect('/login/')


# session的默认过期时间是14天

# 在负载均衡中,如果使用session保存用户信息,会出现session共享问题?那么, 如何解决上述问题?
	常用的缓存数据库就是redis
'''
面试题:
	1. 缓存雪崩
	2. 缓存穿透
	3. 缓存击穿
'''

# 以下在settings.py文件中配置:
	1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

	2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

	3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 

	4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

	5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

	6.其他公用设置项:
SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)

2. CBV添加装饰器

# 在views.py文件中测试:

from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(login_auth, 'get')  # 第二种方式添加
@method_decorator(login_auth, 'get')  # 第二种方式添加 如果没有post 就只需要一次装饰器即可
class IndexView(View):

    @method_decorator(login_auth)  # 第三种方式 给所有的方法添加装饰器
    def dispatch(self, request, *args, **kwargs):  # 第三种方式
        return super().dispatch(request, *args, **kwargs)  # 第三种方式

    # @method_decorator(login_auth)  # 第一种添加方式
    def get(self, request):
        return HttpResponse('get')
    def post(self, request):
        return HttpResponse('post')

image

3. 中间件

# django给我们提供了7个中间件,在配置文件中查询
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# 此外 还支持我们自定义中间件

# 作用:
	1. 校验权限
	2. 限制访问频率
	3. 检查认证
    
# 自定义中间件步骤:
	1. 在任何一个应用下面,创建一个py文件
	2. 在py文件中写一个类必须要继承MiddlewareMixin
	3. 中间写完之后,一定要到配置文件中注册中间件
    
# 需要我们掌握的
	1. process_request
		请求来的时候会走
	2. process_response
		请求走的时候会走
	3. 请求来的时候 会按照配置文件中 注册中间件的顺序自上而下走
		如果在第一个中间件request 给返回值 那么将不会走到下一个中间件 也不会走到视图函数 只走同级别的 response
        

# 代码层面
	1. 在app01目录下 新建 py文件 写入:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class Mydd(MiddlewareMixin):
    def process_request(self, request):
        print('第一个process_request')
        return HttpResponse('第一个process_request')  # 如果在第一个中间件给返回值 那么将不会走到下一个中间件 也不会走到视图函数

    def process_response(self, request, response):
        print('第一个process_response')
        return response  # 必须要返回一个response对象

class Mydd2(MiddlewareMixin):
    def process_request(self, request):
        print('第二个process_request')
        return HttpResponse('第一个process_request')

    def process_response(self, request, response):
        print('第二个process_response')
        return response  # 必须要返回一个response对象
        
        
	2. 到settings.py配置文件中注册:
		找到 MIDDLEWARE = [] 添加
			'app01.center.Mydd',
			'app01.center.Mydd2',

	3. 在views.py中测试功能:
def inner(request):
    return HttpResponse('inner')
"""
如遇到报错 只保留:
def home(request):
    print(request.session.get('username'))
    return HttpResponse('home')
def inner(request):
    return HttpResponse('inner')
    
其余全部注释掉
"""

	4. 添加路由:
		url(r'^inner/', views.inner),
"""
如遇到报错 注释掉多余的路由
"""

image

posted @ 2022-03-09 19:22  Deity_JGX  阅读(33)  评论(0编辑  收藏  举报