我有一个带有视图类的页面模板.在页面模板中,我有一个提交到同一页面的按钮,即
<form method="post" tal:attributes="action request/getURL" >
<input type="hidden" name="filename" value="" tal:attributes="value python:item['filename']" />
<input type="submit" name="form.action.convert" value="Convert" />
</form>
Run Code Online (Sandbox Code Playgroud)
提交表单时,将调用视图类.
class Html(BrowserView):
def __init__(self, context, request):
self.request = request
self.context = context
def __call__(self):
# Is this a form submission via POST?
req = self.request
if req.get('REQUEST_METHOD', 'POST') and \
req.form.get('form.action.convert', '') == 'Convert':
self.convert_document(self.context, str(req.form.get('filename', '')))
def convert_document(self, contextObj, fileToConvert):
""" Do something """
return None
Run Code Online (Sandbox Code Playgroud)
现在,问题是我无法将逻辑放在__init__方法中,因为多次调用此方法,只需单击一次就可以生成多个表单.但是,__call__单击该按钮时会调用该方法一次,但遗憾的是,如果单击链接以查看视图中的当前内容项,则不会发生任何事情,因为该__call__方法被调用且没有任何反应.
我不能在__call__方法中使用下面的代码.浏览器会抱怨页面以永不停止的方式重定向.
self.context.REQUEST.response.redirect( self.context.absolute_url() )
Run Code Online (Sandbox Code Playgroud)
在Plone的页面模板中处理表单提交有更好的方法吗?如何convert_document从页面模板中调用视图类中的方法(即)?
首先,对您的代码进行一些评论,可以简化和改进:
最佳做法是让您的表单使用absolute_url()您的视图方法; 它是规范的URL,request/getURL如果您的视图包含在其他地方,则可能包括获取奇怪或错误的URL:
<form method="post" tal:attributes="action view/absolute_url" >
<input type="hidden" name="filename" value="" tal:attributes="value item/filename" />
<input type="submit" name="form.action.convert" value="Convert" />
</form>
Run Code Online (Sandbox Code Playgroud)
该filename输入框TAL表达式可以只使用一个路径表达式,这些工作的字典就好了.
您不需要重新定义该__init__方法,BrowserView该类已经为您提供了该方法.
为了测试表单是否已提交,我们通常只测试请求中存在的提交按钮,您的测试比需要的更详细:
def __call__(self):
if 'form.action.convert' in self.request.form:
self.convert_document()
Run Code Online (Sandbox Code Playgroud)
因为它convert_document是一种视图方法,它本身可以访问self.context并self.request.form['filename']简化方法签名.既然您现在知道您的表单已提交,那么您可以指望self.request.form['filename']存在并成为一个字符串; 如果不是某人已经手动修补请求而且事情应该破坏,所以我通常不会get(..., '')在这种情况下使用.
视图必须始终在__call__方法中完成所有工作,因为__init__在遍历期间调用视图,此时此类关键信息尚未确定.您不需要redirect通过上下文访问该方法的响应,只需从self.request属性访问它,但记得返回结果:
return self.request.response.redirect(self.context.absolute_url())
Run Code Online (Sandbox Code Playgroud)
但是,如果您的视图是上下文对象的默认视图,那么这确实会导致浏览器无法容忍的重定向循环.
请注意,如果您覆盖具有与之关联的模板__call__的BrowserView视图类的方法,则需要确保在适当的位置返回模板的输出.因此,我对你的观点课的刺激是:
class Html(BrowserView):
def __call__(self):
if 'form.action.convert' in self.request:
self.convert_document()
return self.request.response.redirect(self.context.absolute_url())
return self.index()
def convert_document(self):
""" Do something """
context = self.context
filename = self.request.form['filename']
# Do something with the context and filename
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1366 次 |
| 最近记录: |