如何在GAE上重定向后尽早终止Python Web应用程序?

8

声明:我完全是从PHP背景开始学习Python的。

好的,我正在使用Google App Engine和Google的webapp框架来运行Python。

我有一个函数,我将其导入,因为它包含需要在每个页面上处理的内容。

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        self.redirect('/main/new')

当我调用它时,它运行得很好,但是如何确保重定向后应用程序被终止。我不希望有任何其他处理。例如,我会这样做:

class Dashboard(webapp.RequestHandler):
    def get(self):
        some_function(self)
        #Continue with normal code here
        self.response.out.write('Some output here')

我希望确保在some_function()中进行重定向后(这个过程很顺利),get()函数不会执行任何处理,也不会输出“Some output here”。

为了使所有内容正常工作,我应该查看什么?我不能只退出脚本,因为需要运行webapp框架。

我意识到,很可能我正在完全错误的方式下开发Python应用程序,所以任何指导都将是一个很好的帮助。希望我已经清楚地解释了自己,并且有人能够指引我正确的方向。

谢谢


1
好问题。我认为任何使用 webapp 的 RequestHandler.redirect() 的人在开始使用时都会遇到这个问题。 - David Underhill
3个回答

4

我建议从some_function()返回一个布尔值,根据调用者是否应该继续执行来确定。例如:

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        self.redirect('/main/new')
        return True
    return False

class Dashboard(webapp.RequestHandler):
    def get(self):
        if some_function(self):
            return
        #Continue with normal code here
        self.response.out.write('Some output here')

如果some_function()嵌套层数很深,或者可能有许多类似这样的函数,则还有一种稍微复杂的替代方法可能会有所帮助。思路是:引发一个异常来指示您希望处理停止,并使用webapp.RequestHandler的子类来捕获和忽略此异常。以下是如何进行的大致想法:

class RedirectException(Exception):
    """Raise this from any method on a MyRequestHandler object to redirect immediately."""
    def __init__(self, uri, permanent=False):
        self.uri = uri
        self.permanent = permanent

class RedirectRequestHandler(webapp.RequestHandler):
    def handle_exception(self, exception, debug_mode):
        if isinstance(exception, RedirectException):
            self.redirect(exception.uri, exception.permanent)
        else:
            super(MyRequestHandler, self).handle_exception(exception, debug_mode)

这可能会使与some_function()的工作变得更容易(并使您的其他请求处理程序更易于阅读)。例如:

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        raise RedirectException('/main/new')

class Dashboard(RedirectRequestHandler):
     # rest of the implementation is the same ...

两个很棒的解决方案,第二个让我在学习过程中开阔了思路。返回布尔值是我一直以来的做法,但你已经把它整理得更好了 - 非常感谢你的回复。 - Mike
说实话,我现在才开始理解异常抛出,10分钟后,它开始变得更加清晰,但我认为它仍然超出了我的理解范围。我会研究一下的,非常感谢。 - Mike
布尔方法肯定更简单,对于简单情况(比如你在问题中提出的那个)应该足够了。只需将异常处理方法放在后备方案中,并在布尔方案变得更加棘手时考虑使用它(例如,嵌套函数或像 some_function() 这样的大量函数)。 - David Underhill

4
这个怎么样?
class Dashboard(webapp.RequestHandler):
    def some_function(self):
        if data['user'].new_user and not self.request.path == '/main/new':
            self.redirect('/main/new')
            return True
        else:
            return False
    def get(self):
        if not self.some_function():
            self.response.out.write('Some output here')

如果你需要在许多RequestHandlers中使用some_function()函数,那么编写一个类让其他RequestHandlers可以继承它是符合Python语言风格的做法:

class BaseHandler(webapp.RequestHandler):
    def some_function(self):
        if data['user'].new_user and not self.request.path == '/main/new':
            self.redirect('/main/new')
            return False
        else:
            return True

class Dashboard(BaseHandler):
    def get(self):
        if not self.some_function():
            self.response.out.write('Some output here')

正如我在另一个答案中所评论的,我一直在返回布尔值,但你让它变得更加简洁,同时也开阔了我的思路。我喜欢你关于设置一个类,让RequestHandlers可以从中继承的想法,我会这样做 :) 感谢你指引我成为真正的Python头。我有6年PHP经验...只有几天的Python经验,还有很多要学习! - Mike
我是StackOverflow的新手,这是被标记为已接受的答案,因为我将使用布尔部分和第二个建议来更好地使用Python :) 非常感谢你们两个。 - Mike

0

我知道这个问题很旧,但今天我在做一些事情时自然而然地尝试了另一种解决方案,它运行良好,但我想知道用这种方式是否会有问题。

我的解决方案现在只是返回,实际上可以返回任何内容,但我使用了 "return False",因为存在问题所以我正在打印错误或重定向到其他位置。

通过返回,我已经设置了输出等,并且我提前终止了get()或post()函数。

这是一个可以的解决方案吗?


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