对不起书呆子的问题,但我花了2天但找不到任何解决方案。
这是我的route.py配置
app = WSGIApplication(
routes=[
Route("/account", handler="app.account.Settings")
]
)
我创建了一个像这样的Handler(需要登录)
@HealthPortRequestHandler.login_required
class Settings(HealthPortRequestHandler):
def get(self):
self.render("account/settings.html")
并创建login_required验证方法
@cached_property
def check_user_logged_in(self):
if self.request.cookies.get("User"):
user_id = self.read_cookie("User")
if user_id:
from models.users import Users
return Users.get_by_id(int(user_id))
else:
return None
return None
@staticmethod
def login_required(handler):
def check_login(self, *args, **kwargs):
if self.check_user_logged_in:
return handler(self, *args, **kwargs)
else:
return self.redirect("/login")
return check_login
但在此行调试时发现错误
if self.check_user_logged_in:
有错误 引发AttributeError(attr)
AttributeError: check_user_logged_in
我怎么知道到底发生了什么?任何想法?
答案 0 :(得分:1)
您正在将装饰器login_required
应用于类Settings
,因此装饰器将在创建Settings
实例时执行。
当您尝试创建Settings
的实例时,会调用check_login
中的login_required
函数。它收到的参数是传递给Setting
的{{1}}方法的值。然后__init__
将它收到的第一个值作为参数,并尝试访问其check_login
属性。无论它是什么(可能是webapp2.Request对象),该值都没有check_user_logged_in
属性,因此会引发异常。
这可以在不使用webapp2框架的情况下进行演示:
check_user_logged_in
这就是你得到AttributeError的原因。
要修复它,我建议装饰请求处理程序的调度方法而不是类定义。这样,您仍然可以在处理请求之前进行检查,但可以访问完全初始化的class HealthPortRequestHandler(object):
def __init__(self, *args, **kwargs):
pass
@property
def check_user_logged_in(self):
pass
@staticmethod
def login_required(handler):
def check_login(self, *args, **kwargs):
if self.check_user_logged_in:
return handler(self, *args, **kwargs)
else:
raise RuntimeError('Not expecting to execute this')
return check_login
@HealthPortRequestHandler.login_required
class Settings(HealthPortRequestHandler):
pass
>>> s = Settings('Hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "demo.py", line 14, in check_login
if self.check_user_logged_in:
AttributeError: 'str' object has no attribute 'check_user_logged_in'
>>> s = Settings(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "demo.py", line 14, in check_login
if self.check_user_logged_in:
AttributeError: 'int' object has no attribute 'check_user_logged_in'
>>> s = Settings('Hello', 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "deco.py", line 14, in check_login
if self.check_user_logged_in:
AttributeError: 'str' object has no attribute 'check_user_logged_in'
实例。