python - 在 Plone 模板中处理表单提交

标签 python plone

我有一个带有 View 类的页面模板。在页面模板中,我有一个提交到同一页面的按钮,即

<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>

提交表单时,调用 View 类。

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

现在,问题是我无法将逻辑放在 __init__ 方法中,因为多次调用此方法,导致只需单击一次即可提交多个表单。但是,单击按钮时将调用一次 __call__ 方法,但不幸的是,如果我单击一个链接以查看 View 中的当前内容项,则没有任何反应,因为 __call__ 方法被调用但没有任何反应。

我不能在 __call__ 方法中使用下面的代码。浏览器会提示页面正在以一种永无止境的方式重定向。

self.context.REQUEST.response.redirect( self.context.absolute_url() )

在 Plone 的页面模板中是否有更好的处理表单提交的方法?如何从页面模板调用 View 类中的方法(即 convert_document)?

最佳答案

首先,对你的代码进行一些评论,它可以简化和改进:

最佳做法是让您的表单使用 View 的 absolute_url() 方法;这是规范的 URL,而 request/getURL 可能包含获取异常或如果您的 View 包含在其他地方则完全错误的 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>

filename输入框的tal表达式可以只用路径表达式,这些对字典很管用。

您不需要重新定义 __init__ 方法,BrowserView 类已经为您提供了该方法。

为了测试表单是否已提交,我们通常只测试请求中是否存在提交按钮,您的测试比需要的更详细:

def __call__(self):
    if 'form.action.convert' in self.request.form: 
        self.convert_document()

因为 convert_document 是你 View 的一个方法,它本身可以访问 self.contextself.request.form['filename'],简化您的方法签名。由于您现在知道您的表单已提交,您可以指望 self.request.form['filename'] 存在并且是一个字符串;如果不是有人手动修改了请求,那么事情就应该中断,所以在这种情况下我通常不会使用 get(..., '')

View 必须始终在 __call__ 方法中完成所有工作,因为 __init__ 在遍历期间被调用,此时像当前用户这样的关键信息还没有被确定。您不需要通过上下文访问 redirect 方法的响应,只需从 self.request 属性访问它即可,但请记住 return 结果:

return self.request.response.redirect(self.context.absolute_url())

但是,如果您的 View 是上下文对象的默认 View ,那确实会导致浏览器无法容忍的重定向循环。

请注意,如果您确实覆盖了具有关联模板的 BrowserView View 类的 __call__ 方法,则需要确保返回模板在适当的地方。因此,我对您的 View 类的尝试是:

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

关于python - 在 Plone 模板中处理表单提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12910348/

相关文章:

python - Scrapy不会选择嵌入元素

python - 将包含逗号分隔值的字符串转换为整数

python - 超出范围后,文件句柄是否会在 Python 中自动关闭?

timezone - Plone MailHost 发送带有澳大利亚时区的错误日期 header

session - 基于 Memcached 的烧杯 session 未在 Zope 启动时初始化

python - 无法访问 postgresql 表

mysql - Plone + SqlAlchemy + MySql 中未提交的事务

macos - 无法在 MacOS High Sierra (10.13.3) 上安装 Plone 5.0.8

plone - 在 Chameleon 中使用 tal 宏

python - Pytorch 训练和评估不同的样本量