Django 中 request.user 为什么是 SimpleLazyObject

栏目: Python · 发布时间: 6年前

内容简介:我遇到了一个问题,刚开始我以为这样做的是不是能保持的用户登录状态而不用每次请求都查询数据库。

起步

我遇到了一个问题, request.user 并不是用户模型,而是 django.utils.functional.SimpleLazyObject 的实例。可以猜测它是用了某种惰性的载入方式。

源起中间件

request.user 是在何时进行赋值的呢?在中间件 django.contrib.auth.middleware.AuthenticationMiddleware 中:

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = SimpleLazyObject(lambda: get_user(request))

刚开始我以为这样做的是不是能保持的用户登录状态而不用每次请求都查询数据库。

但经过测试后发现,懒加载并不能减少数据库的查询。甚至匿名用户也是每次请求都是不同的对象的。

这下好了,我感觉它没什么用处,根本就是多次一举。Django 为什么要选择惰性加载来处理用户模型呢?

原因

要想知道为什么这样处理,要先知道 SimpleLazyObject 是如何惰性载入的。

class SimpleLazyObject(LazyObject):
    def __init__(self, func):
        self.__dict__['_setupfunc'] = func
        super().__init__()

    def _setup(self):
        self._wrapped = self._setupfunc()

它的作用就是先将方法放入 _setupfunc 中,在合适的时候调用 _setup() 方法将其执行。

合适的时候就是当放到到对象的属性的时候。这里就能知道为什么用惰性载入处理用户模型了。对于一些公共资源(公共api,静态文件),其实是不需要对用户进行认证操作的,在这部分请求里由于没有访问 request.user 的属性,就不会有查询数据库的操作了。

这就是用 SimpleLazyObject 处理用户模型的原因了。

如何获取request中的用户模型

如果是进行身份验证然后访问 request.user ,则会返回一个几乎等同于 User 的实例,已经能满足项目需求了。虽然是这么说,但它其实仍然是 SimpleLazyObject 类型的。

SimpleLazyObject 代码中可以看出,User 对象是储存 _wrapped 中的,所以通过 request.user._wrapped 就能得到实际的 User 对象了。

这里强调的是,需要事先对 user 里的属性进行访问。看下面的例子:

from django.utils.functional import SimpleLazyObject

class A():
    def __init__(self):
        self.name = 'x'
    def __str__(self):
        return 'x'

class S():
    def __init__(self):
        self.a = SimpleLazyObject(lambda :A())

s1 = S()
s2 = S()

print(s1.a, type(s1.a), s1.a._wrapped, type(s1.a._wrapped)) # x <class 'django.utils.functional.SimpleLazyObject'> <object object at 0x0> <class 'object'>
s2.a.name   # 在访问了 a 的属性之后
print(s2.a, type(s2.a), s2.a._wrapped, type(s2.a._wrapped)) # x <class 'django.utils.functional.SimpleLazyObject'> x <class '__main__.A'>

由于惰性的机制,如果没有对属性访问的话,得到的 _wrapped 仍然是空白的。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Numerical Methods and Methods of Approximation in Science and En

Numerical Methods and Methods of Approximation in Science and En

Karan Surana / CRC Press / 2018-10-31

ABOUT THIS BOOK Numerical Methods and Methods of Approximation in Science and Engineering prepares students and other readers for advanced studies involving applied numerical and computational anal......一起来看看 《Numerical Methods and Methods of Approximation in Science and En》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具