Django中如何动态地给HttpRequest实例添加属性?

3
我对Django中的HttpRequest对象感到困惑。我知道AuthenticationMiddleware会向request添加一个user,该请求是HttpRequest的实例。代码在这里,但我想要展示的内容如下: request.user = SimpleLazyObject(lambda: get_user(request)) 我已经阅读了HttpRequest对象的代码,但找不到user属性及其代码没有__setattr__方法。因此,我很好奇为什么访问不存在的属性时代码没有引发AttributeError。
感谢提供帮助。

1
我不明白你在问什么,Python会允许你在需要的地方添加属性/字段吗? - Sayse
如果HttpRequest没有像user这样的属性,则编写request.user将引发AttributeError异常。 - chyoo CHENG
但是,任何时候当您需要使用它时,它都将具有该属性,因为它已添加到身份验证中间件中。您是否尝试在此中间件运行之前在自己的中间件中使用它? - Sayse
不,我想问的是为什么代码没有引发AttributeError。 - chyoo CHENG
1个回答

6

HttpRequest是继承自object的一个类。在Python中,属性可以随时设置在对象上。

HttpRequest描述了一个HTTP请求,它的正常状态下不包括任何关于用户的数据。这就是为什么AuthenticationMiddleware会在请求中添加user的原因。


__setitem__是用于在对象上设置索引项的方法。

__setattr__是用于在对象上设置属性的方法,也是object中实现的方法之一。


更新
如@sayse所说,那就是获取。

>>> class Test(object):
    pass

>>> test = Test()
>>> test.user #Try to access an unset attribute
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    test.user #Try to access an unset attribute
AttributeError: 'Test' object has no attribute 'user'
>>> test.user = 'user' #Set user attribute
>>> test.user #Try to access user
'user'

在Python中,属性可以随时设置在对象上。但是我对这句话有所怀疑。例如:class Test(object):passt = Test(),然后t.user会引发AttributeError。 - chyoo CHENG
@chyooCHENG - 这是获取,而不是设置。(顺便说一句,James Fenwick 写得很好) - Sayse
我已经理解了。谢谢大家! - chyoo CHENG
我想知道为什么它可以运行,是因为对象实现了__setarr__方法吗?@James Fenwick - chyoo CHENG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接