Cookie&&Session:

cookie常见使用

from django.urls import path
from django.shortcuts import HttpResponse


def x1(request):
    # 包含:响应体、响应头、状态码等信息
    obj = HttpResponse("x1", status=201, reason="OK")
    # 设置响应头
    obj['name'] = "admin"

    # 设置cookie
    # import datetime
    # ctime = datetime.datetime.now() + datetime.timedelta(seconds=10)
    
    obj.set_cookie("v3", "root", max_age=10, path="/")
    obj.set_cookie("v2", "hello")
    obj.set_signed_cookie("info", "qwe123")  # 签名
    return obj


def x2(request):
    print(request.COOKIES)
    xx = request.get_signed_cookie("info")  # 用户不能自己修改cookie的内容
    print(xx)
    # print(request.COOKIES.get('v1'))
    # print(request.COOKIES.get('v2'))
    return HttpResponse("x2")


urlpatterns = [
    path('x1/', x1, name='x1'),
    path('x2/', x2, name='x2'),
]

django框架的使用及其梳理系列五_数据库

Cookie的实现:

#HttpResponse的父类
class HttpRequest:
    def __setitem__(self, header, value):
        self.headers[header] = value
        
    def set_cookie(self,key,value="",...):
        self.cookies[key] = value
        
    def get_signed_cookie(self, key, default=RAISE_ERROR, salt="", max_age=None):
        cookie_value = self.COOKIES[key]
        value = signing.get_cookie_signer(salt=key + salt).unsign(cookie_value, max_age=max_age)
		return value

class WSGIRequest(HttpRequest):
    def __init__(self, environ):
        self.environ = environ
        ...
        
    @cached_property
    def COOKIES(self):
        raw_cookie = get_str_from_wsgi(self.environ, "HTTP_COOKIE", "")
        return parse_cookie(raw_cookie)

回到入口的call方法:

  status = '%d %s' % (response.status_code, response.reason_phrase)
    #将字典的数据打散传进去
    #在response中读取所有的请求头
    #读取所有cookie
        response_headers = [
            *response.items(),
            *(('Set-Cookie', c.output(header='')) for c in response.cookies.values()),
        ]


v1 = {"name": "张三", "salary": 8000}
print(v1.items())
response_headers = [*v1.items()]
print(response_headers)

django框架的使用及其梳理系列五_数据库_02

WSGIRequest,请求

class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.load_middleware()

    def __call__(self, environ, start_response):
        set_script_prefix(get_script_name(environ))
        signals.request_started.send(sender=self.__class__, environ=environ)

        request = self.request_class(environ)
        
class HttpRequest:
    def get_signed_cookie(self, key, default=RAISE_ERROR, salt="", max_age=None):
        cookie_value = self.COOKIES[key]
        value = signing.get_cookie_signer(salt=key + salt).unsign(cookie_value, max_age=max_age)
		return value

class WSGIRequest(HttpRequest):
    def __init__(self, environ):
        self.environ = environ
        ...
        
    @cached_property
    def COOKIES(self):
        raw_cookie = get_str_from_wsgi(self.environ, "HTTP_COOKIE", "")
        return parse_cookie(raw_cookie)        

Session

############
# SESSIONS #
############
# Session存储在哪里?
SESSION_ENGINE = "django.contrib.sessions.backends.db"

# 如果存储到文件中,文件的路径。
SESSION_ENGINE = "django.contrib.sessions.backends.file"
SESSION_FILE_PATH = None

# 存储到缓存
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"


# 存储到缓存 + 数据库
SESSION_ENGINE = "django.contrib.sessions.backends.cache_db"
SESSION_CACHE_ALIAS = "default"

# 存储到cookie
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"

# class to serialize session data
SESSION_SERIALIZER = "django.contrib.sessions.serializers.JSONSerializer"


# -------------------------------
# Cookie name. This can be whatever you want.
SESSION_COOKIE_NAME = "sessionid"
# Age of cookie, in seconds (default: 2 weeks).
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
# A string like "example.com", or None for standard domain cookie.
SESSION_COOKIE_DOMAIN = None
# Whether the session cookie should be secure (https:// only).
SESSION_COOKIE_SECURE = False
# The path of the session cookie.
SESSION_COOKIE_PATH = "/"
# Whether to use the HttpOnly flag.
SESSION_COOKIE_HTTPONLY = True
# Whether to set the flag restricting cookie leaks on cross-site requests.
# This can be 'Lax', 'Strict', 'None', or False to disable the flag.
SESSION_COOKIE_SAMESITE = "Lax"
# Whether to save the session data on every request.
SESSION_SAVE_EVERY_REQUEST = False
# Whether a user's session cookie expires when the web browser is closed.
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
  • 注意:如果是非数据库,可以主调用app的注册代码部分。
  • 请求=登录,生成Session、Cookie。
  • 再次请求,默认携带cookie,根据Cookie中的凭证,去找到Session中原本存储的数据。
演示
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
]

django启动,加载

class SessionMiddleware(MiddlewareMixin):
    # RemovedInDjango40Warning: when the deprecation ends, replace with:
    #   def __init__(self, get_response):
    def __init__(self, get_response=None):
        super().__init__(get_response)
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore


  
请求发出:
  
  ```python
  
  def process_request(self, request):
      # 1.去Cookie中读取凭证 mid="123456"
      session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
      # 2.实例化
      request.session = self.SessionStore(session_key)

这里我用数据库

SESSION_ENGINE = "django.contrib.sessions.backends.db"

  mysql
  create database temp_session charset utf8 collate utf8_general_ci;
  #settings.py
  
  DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.mysql',
          'NAME': 'temp_session',  # 数据库名字
          'USER': 'root',
          'PASSWORD': 'root123',
          'HOST': '127.0.0.1',  # 那台机器安装了MySQL
          'PORT': 3306,
      }
  }
  
  #urls.py
  from django.urls import path
  from django.shortcuts import HttpResponse
  
  def x1(request):
      request.session['id'] = 999
      # 类中的__setitem__
      request.session['name'] = 'admin'
      request.session['age'] = '25'
      return HttpResponse("x1")
  
  urlpatterns = [
      path('x1/', x1, name='x1'),
  ]

随便访问一个路由

django框架的使用及其梳理系列五_HTTP_03