[学习笔记] django学习笔记(2)

2021-12-30 11:52:37 浏览数 (1)

django中session的源码解析以及使用

在大部分网站中,都需要用到用户id以及登陆状态,这时候就需要用到session。

说一说session概念:

Session是存在server端,当client向server发起request的时候,会产生一个session,用来存放client的一些信息,比如id等,当然这些信息是我们可以自己设置需要存什么。每个client有一个唯一的sessionid,所以对于不同client,他们用自己的sessionid拿到的信息都是自己的。

说到这里,有一个非常经典的面试题:

请说一说session和cookie的区别?具体答案我就不在这里介绍了。不知道的朋友们可以在网上搜一搜。

今天介绍一下django中的session。

Django中的session是一个中间件,可以倒入这个包查看。django.contrib.sessions.middleware

代码语言:javascript复制
import time

from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
from django.utils.importlib import import_module

class SessionMiddleware(object):
    def process_request(self, request):
        engine = import_module(settings.SESSION_ENGINE)
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
        request.session = engine.SessionStore(session_key)

    def process_response(self, request, response):
        """
        If request.session was modified, or if the configuration is to save the
        session every time, save the changes and set a session cookie.
        """
        try:
            accessed = request.session.accessed
            modified = request.session.modified
        except AttributeError:
            pass
        else:
            if accessed:
                patch_vary_headers(response, ('Cookie',))
            if modified or settings.SESSION_SAVE_EVERY_REQUEST:
                if request.session.get_expire_at_browser_close():
                    max_age = None
                    expires = None
                else:
                    max_age = request.session.get_expiry_age()
                    expires_time = time.time()   max_age
                    expires = cookie_date(expires_time)
                # Save the session data and refresh the client cookie.
                # Skip session save for 500 responses, refs #3881.
                if response.status_code != 500:
                    request.session.save()
                    response.set_cookie(settings.SESSION_COOKIE_NAME,
                            request.session.session_key, max_age=max_age,
                            expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
                            path=settings.SESSION_COOKIE_PATH,
                            secure=settings.SESSION_COOKIE_SECURE or None,
                            httponly=settings.SESSION_COOKIE_HTTPONLY or None)
        return response

Django中的session是一个中间件,可以倒入这个包查看。django.contrib.sessions.middleware

从上面可以看到session这个中间件的源码其实非常简单。

我们先来看看process_request这个函数。这个函数是请求来的时候调用的。

他首先是加载了一个引擎,就是下面讲到的五种session的模式,可以在setting中自己设置。

然后是去request对象中的cookie 拿到SESSION_COOKIE_NAME,SESSION_COOKIE_NAME也是自己设置的,一般设置成”seesionid”

然后是从引擎中拿到数据。放在request对象的session中。

所以,其实我们的sessionid是从请求的cookie里拿到的,然后在这个中间件里根据sessionid去查找存储在服务器上的数据,然后设置在request对象的session里。

在看process_response这个函数。

我们看到有两个值,accessed 和modified.我们可以在SessionBase这个对象里看到这两个值,

在读取等操作以后,accessed就会被设置成True

在设置等操作以后,modified就会被设置成False

具体哪些操作会被设置,可以在SessionBase中查看。

在代码中可以看到,如果被访问过,那么respone 会把cookie这个字符串放在vary头部中

如果修改过,会进行一个判断:get_expire_at_browser_close

可以看一下这个函数的描述:

Returns ``True`` if the session is set to expire when the browser closes, and ``False`` if there's an expiry date. Use ``get_expiry_date()`` or ``get_expiry_age()`` to find the actual expiry date/age, if there is one.

这一部分其实就是对过期时间对一个设置。

如果返回不为500的话,就把session保存,然后把sessionid/过期时间等信息设置到cookie中返回给client。

介绍一下session的流程

django中的session是需要配合cookie一起使用的。步骤如下:

1.在发起请求的时候,服务器通过django的session设置信息,并生成唯一的session_id。

例如发起请求的user,他的id为1,名字为root

request.session[‘id’] = 1

request.session[‘name’] = ‘root’

这样session就设置好了,django中会把键值对存到一张表中

2.server在处理完请求以后,sessionid返回并存在cookie中

3.client再次访问该server,会带着之前cookie去访问

在服务器端,django直接使用request对象中的session,既可以拿到该client对应的sessionid里的所有信息。

例如获取id和name

Id = request.session.get(“id”)

Name = request.session.get(“name”)

Django中提供了五种模式的session供开发者使用:

1.数据库,这种是默认模式,即sessionid 和data是存在数据表中的

2.缓存

3.文件

4.缓存 数据库

5.加密cookie

我们可以在代码中看到这些被取名engine,其实从名字上也可以看出来,这些模式或者叫引擎到区分大多是根据存储的形式进行区分。

讲点实用的,django中如何操作session,即session的一些基本方法:

1.写session

request.session[key] = value

2.读session

value = request.session.get(key,”default”)

value = request.session[key]

3.清空session

request.session.clear()

4.删除session 数据,并在存储中删除整条数据

request.session.flush()

5.删除某个key

del request.session[key]

6.设置session有效时间

request.session.set_expiry(value)

0 人点赞