Cookie的缺点
Cookie保存在浏览器端,不安全
Cookie的长度不能超过4096字节
Session是什么?
保存在服务器端的键值对
Session相关方法 # 获取、设置、删除Session中数据 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在则不设置 del request.session['k1'] # 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 会话session的key request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查会话session的key在数据库中是否存在 request.session.exists("session_key") # 删除当前会话的所有Session数据 request.session.delete() # 删除当前的会话数据并删除会话的Cookie。 request.session.flush() 这用于确保前面的会话数据不可以再次被用户的浏览器访问 例如,django.contrib.auth.logout() 函数中就会调用它。 # 设置会话Session和Cookie的超时时间 request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
Session流程解析
from functools import wraps def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.session.get("user"): return func(request, *args, **kwargs) else: return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") if user == "alex" and pwd == "alex1234": # 设置session request.session["user"] = user # 获取跳到登陆页面之前的URL next_url = request.GET.get("next") # 如果有,就跳转回登陆之前的URL if next_url: return redirect(next_url) # 否则默认跳转到index页面 else: return redirect("/index/") return render(request, "login.html") @check_login def logout(request): # 删除所有当前请求相关的session request.session.delete() return redirect("/login/") @check_login def index(request): current_user = request.session.get("user", None) return render(request, "index.html", {"user": current_user})
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' # 引擎 其他公用设置项: 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,默认修改之后才保存(默认)
Django提供的装饰器工具 from django.utils.decorators import method_decorator --> 把装饰函数的装饰器包装成可以装饰类中方法的装饰器
from django.utils.decorators import method_decorator class HomeView(View): def dispatch(self, request, *args, **kwargs): return super(HomeView, self).dispatch(request, *args, **kwargs) def get(self, request): return render(request, "home.html") @method_decorator(check_login) def post(self, request): print("Home View POST method...") return redirect("/index/")
from django.utils.decorators import method_decorator class HomeView(View): @method_decorator(check_login) def dispatch(self, request, *args, **kwargs): return super(HomeView, self).dispatch(request, *args, **kwargs) def get(self, request): return render(request, "home.html") def post(self, request): print("Home View POST method...") return redirect("/index/")
from django.utils.decorators import method_decorator @method_decorator(check_login, name="get") @method_decorator(check_login, name="post") class HomeView(View): def dispatch(self, request, *args, **kwargs): return super(HomeView, self).dispatch(request, *args, **kwargs) def get(self, request): return render(request, "home.html") def post(self, request): print("Home View POST method...") return redirect("/index/")
csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
在CBV只能加到dispatch方法上,或者加在视图类上然后name参数指定为dispatch方法。
中间件
中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。
中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
不同中间件之间传递的request都是同一个对象
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1里面的 process_request") def process_response(self, request, response): print("MD1里面的 process_response") return response
1. process_request(self,request) ***** 0. 执行的时间点: 请求进来之后 1. 执行顺序: 按照中间件的注册顺序执行 2. 参数 当前请求对象 3. 返回值 1. 返回None继续执行后续的 2. 返回响应对象,不继续执行后续的流程,直接返回响应 2. process_response(self, request, response) ***** 0. 执行的时间点: 返回响应之后 1. 执行顺序: 按照中间件注册的倒序执行 2. 参数 1. request:当前的请求对象 2. response: 传递过来的响应对象 3. 返回值: 1. 必须返回一个响应对象 3. process_view(self, request, view_func, view_args, view_kwargs) 0. 执行的时间点: process_request之后,视图函数之前执行 1. 执行顺序 按照注册的顺序执行 2. 参数 1. request:请求对象 2. view_func: 将要执行的视图函数对象 3. view_args/view_kwargs: 将要执行的函数的参数 3. 返回值 1. None:继续往后执行 2. 响应对象: 直接返回了,不会执行后续的视图函数 4. process_template_response(self,request,response) 0. 执行的时间点 当视图函数中返回带render方法的响应对象,这个方法才会执行 1. 执行顺序: 注册的倒序 2. 参数: 1. request:请求对象 2. response:响应对象 3. 返回值 1. 必须返回响应对象 5. process_exception(self, request, exception) 0. 执行的时间点 当视图函数中抛出异常的时候才会执行这个方法 1. 执行顺序: 注册的倒序 2. 参数: 1. request:请求对象 2. exception: 视图函数抛出的异常 3. 返回值: 1. None:继续执行后续 2. 响应对象: 直接返回
中间件执行流程