2012-10-16 21 views
3

我有一個帶有視圖類的頁面模板。在頁面模板,我有一個按鈕,提交到同一頁面即在Plone模板中處理表單提交

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

當表單提交時,視圖類被調用。現在

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__方法,但不幸的是,如果我單擊鏈接以查看視圖中的當前內容項,則不會發生任何事情,因爲__call__方法被調用並且什麼都不會發生。

我不能使用__call__方法中的以下代碼。瀏覽器會抱怨該頁面將以永不結束的方式重定向。

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

在Plone的頁面模板中處理表單提交是否有更好的方式?如何在頁面模板的視圖類中調用我的方法(即convert_document)?

回答

6

首先,在您的代碼一些評論,它可以被簡化和改進:

最好的做法是爲表單使用您的視圖的方法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> 

filename輸入框TAL表達式可以只使用一個路徑表達式,這些工作的字典就好了。

您不需要重新定義__init__方法,BrowserView類已經爲您提供。

測試如果表已提交,我們一般只是測試提交按鈕存在於請求,你的測試是更復雜的比需要的:

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

因爲convert_document是一個方法你查看,它本身可以訪問self.contextself.request.form['filename'],簡化您的方法簽名。既然你現在知道你的表單已經提交,你可以指望self.request.form['filename']存在並且是一個字符串;如果不是有人已經手動修改了請求,並且事情值得打破,那麼在這種情況下我通常不會使用get(..., '')

視圖必須始終在__call__方法中完成所有工作,因爲在遍歷期間調用__init__,此時當前用戶等重要信息尚未確定。你並不需要通過上下文來訪問的響應爲redirect方法,從self.request屬性只訪問它,但記得要回報結果:

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

但是,如果你的觀點是默認上下文對象的視圖,這確實會導致瀏覽器不能容忍的重定向循環。

請注意,如果您確實覆蓋了具有與其關聯的模板的BrowserView視圖類的__call__方法,則需要確保在適當的情況下返回模板的輸出。我的刺你的視圖類將因此是:

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

謝謝你仔細分析我的代碼。只是說明我對Plone的瞭解還有多少。嬰兒的步驟。如果我只有一半的知識。關於你的答案,是的,它的工作很好。我失蹤了self.index() – Frankline