Google App Engine,定义一个预处理类

发布于 2024-10-08 14:12:14 字数 1841 浏览 7 评论 0原文


我试图定义一个基本请求处理类,以便Web应用程序页面可以继承一些基本方法和变量,否则需要为应用程序的每个页面重复定义这些方法和变量。类似于 django 预处理器的类似功能。这是我的基类,其他页面从中继承:

class BasePage(webapp.RequestHandler):
    def __init__(self):    
        self.user = users.get_current_user()    
        self.template_values = {
                'user': self.user,       
                'environ': self,   #I don't like the idea of passing the whole environ object to a template

                ##The below three functions cannot be executed during _init_ because of absence of self.request 
                #'openid_providers': self.openid_providers(),  
                #'logout_url': self.get_logout_url(),
                #'request': self.get_request(),
            }           

    ##A sort of similar functionality like render_to_response in django
    def render_template(self, template_name, values = None, *args, **kwargs):
        #PATH is the directory containing the templates
        if values: 
            for value in values:  self.template_values[value] = values[value]
        self.response.out.write(template.render(PATH+template_name, self.template_values, *args, **kwargs))                 

    ##Returns request as the name suggests
    def logout_url(self):
        return users.create_logout_url(self.request.url)

    ##Returns request as the name suggests
    def request(self):
        return request

    ##Returns openid login urls        
    def openid_providers(self):
        #OPENID_POVIDERS  is a list of dictionary 
        for p in OPENID_PROVIDERS:
             p['login_url'] = users.create_login_url(self.request.get('next', '/') , p['name'], p['url'])
        return OPENID_PROVIDERS  

一切工作正常,除了我无法在初始化期间传递一些变量,因为 self.request 不可用。因此,对于解决方法,我所做的是将整个 self 变量作为模板变量传递。

是否有其他方法向模板提供模板变量(request、logout_url 等)?

I am trying to define a base request handling class so that the webapp pages may inherit some basic methods and variable which otherwise would be required to be repeatedly be defined for each page of the application. A sort of similar functionality like django preprocessors. This is my base class from which other pages inherit:

class BasePage(webapp.RequestHandler):
    def __init__(self):    
        self.user = users.get_current_user()    
        self.template_values = {
                'user': self.user,       
                'environ': self,   #I don't like the idea of passing the whole environ object to a template

                ##The below three functions cannot be executed during _init_ because of absence of self.request 
                #'openid_providers': self.openid_providers(),  
                #'logout_url': self.get_logout_url(),
                #'request': self.get_request(),
            }           

    ##A sort of similar functionality like render_to_response in django
    def render_template(self, template_name, values = None, *args, **kwargs):
        #PATH is the directory containing the templates
        if values: 
            for value in values:  self.template_values[value] = values[value]
        self.response.out.write(template.render(PATH+template_name, self.template_values, *args, **kwargs))                 

    ##Returns request as the name suggests
    def logout_url(self):
        return users.create_logout_url(self.request.url)

    ##Returns request as the name suggests
    def request(self):
        return request

    ##Returns openid login urls        
    def openid_providers(self):
        #OPENID_POVIDERS  is a list of dictionary 
        for p in OPENID_PROVIDERS:
             p['login_url'] = users.create_login_url(self.request.get('next', '/') , p['name'], p['url'])
        return OPENID_PROVIDERS  

Everything is working fine except that I cannot pass some variables during initialization as self.request is not available. So for a workaround what I did is pass on whole self variable as a template variable.

Is there some other way to provide the template variables (request, logout_url etc) to the templates?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如歌彻婉言 2024-10-15 14:12:14

比 bgporter 更简单的解决方案是在 webapp.RequestHandlerinitialize 方法中进行常见设置。这是工作中的一个示例,我们想要向请求对象添加一个类似 Django 的 is_ajax 方法:

class BaseHandler(webapp.RequestHandler):
    def initialize(self, request, response):
        super(BaseHandler, self).initialize(request, response)
        # Add a Django-like is_ajax() method to the request object
        request.is_ajax = lambda: \
            request.environ.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

调用此方法是为了,呃,在之前使用当前请求和响应对象初始化每个请求处理程序调用适当的 getpost (或其他)方法。

A much simpler solution than bgporter's is to do the common setup in the initialize method of webapp.RequestHandler. Here's an example from work, where we wanted to add a Django-like is_ajax method to the request object:

class BaseHandler(webapp.RequestHandler):
    def initialize(self, request, response):
        super(BaseHandler, self).initialize(request, response)
        # Add a Django-like is_ajax() method to the request object
        request.is_ajax = lambda: \
            request.environ.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

This method is called to, uh, initialize each request handler with the current request and response objects, before the appropriate get or post (or whatever) methods are called.

許願樹丅啲祈禱 2024-10-15 14:12:14

我已经通过使用模板方法模式在我的AppEngine代码中解决了这个问题

基本上,基类看起来像:

class MyBasePage(webapp.RequestHandler):
    def __init__(self):
        # common setup/init stuff here, 
        # omitted for this discussion

    def Setup(self):
        # request handling setup code needed in both GET/POST methods, like
        # checking for user login, getting session cookies, etc.
        # omitted for this discussion

    def get(self, *args):
        self.Setup()
        # call the derived class' 'DoGet' method that actually has 
        # the logic inside it
        self.DoGet(*args)

    def post(self, *args):
        self.Setup()
        # call the derived class' 'DoPost' method 
        self.DoPost(*args)

    def DoGet(self, *args):
        ''' derived classes override this method and 
            put all of their GET logic inside. Base class does nothing.'''
        pass

    def DoPost(self, *args):
        ''' derived classes override this method and 
            put all of their POST logic inside. Base class does nothing.'''
        pass

...您的派生类大多只需要担心这些 DoGet()DoPost() 方法的内部内容。

I've solved that problem in my AppEngine code by using the Template Method Pattern

Basically, the base class looks like:

class MyBasePage(webapp.RequestHandler):
    def __init__(self):
        # common setup/init stuff here, 
        # omitted for this discussion

    def Setup(self):
        # request handling setup code needed in both GET/POST methods, like
        # checking for user login, getting session cookies, etc.
        # omitted for this discussion

    def get(self, *args):
        self.Setup()
        # call the derived class' 'DoGet' method that actually has 
        # the logic inside it
        self.DoGet(*args)

    def post(self, *args):
        self.Setup()
        # call the derived class' 'DoPost' method 
        self.DoPost(*args)

    def DoGet(self, *args):
        ''' derived classes override this method and 
            put all of their GET logic inside. Base class does nothing.'''
        pass

    def DoPost(self, *args):
        ''' derived classes override this method and 
            put all of their POST logic inside. Base class does nothing.'''
        pass

...your derived classes then mostly just need to worry about the guts of those DoGet() and DoPost() methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文