使用python在GAE中使用@cached_property请求处理程序

时间:2017-03-04 15:05:09

标签: python google-app-engine

对不起书呆子的问题,但我花了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

我怎么知道到底发生了什么?任何想法?

1 个答案:

答案 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' 实例。