我正在尝试定义一个base request handling
类,以便webapp页面可以继承一些基本方法和变量,否则需要为应用程序的每个页面重复定义。一种类似django preprocessors
的功能。这是我的基类,其他页面继承该基类:
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不可用。因此,对于解决方法,我所做的是将整个自变量作为模板变量传递。
是否有其他方法可以为模板提供模板变量(request,logout_url等)?
答案 0 :(得分:5)
比bgporter更简单的解决方案是在initialize
webapp.RequestHandler
方法中进行常规设置。以下是工作中的示例,我们希望在请求对象中添加类似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'
在调用适当的get
或post
(或其他)方法之前,调用此方法,呃,用当前请求和响应对象初始化每个请求处理程序。
答案 1 :(得分:2)
基本上,基类看起来像:
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()
方法的内容。