2014-11-14 64 views
2

在我正在處理的plone站點上,我有一個表單,用於編輯映射到後端數據庫表中的對象的記錄。在接口類中,其中一個字段是schema.Datetime字段。Zope.Schema/Plone - 如何在updateWidget函數中設置Datetime字段的值?

class ICalibration(Interface): 
"""Interface class for calibration records 
""" 
... 
    Last_Calibration = schema.Datetime(title=u"Last Calibration" 
             description=u"date of last calibration", 


            ) 
... 

在我updateWidgets功能,在編輯表格,我嘗試設置控件的值,

class EditCalibration(form.Form): 
    grok.name('edit-calibration') 
    grok.require('zope2.View') 
    grok.context(ISiteRoot) 

    def updateWidgets(self): 
     super(EditCalibration, self).updateWidgets() 
     id = self.request.get('id',None) 

     if id: 
      currentCal = session.query(Calibration).filter(Calibration.Calibration_ID == id).one() 

      ... 
      self.widgets["Last_Calibration"].value = currentCal.Last_Calibration 
     ... 

,但我得到這個錯誤:

「類型錯誤:「日期時間。日期時間」對象有沒有屬性‘的GetItem’。

我曾嘗試一些事情,是那種有趣。 我打印出Cal.Last_Calibration的值,並將其作爲我添加記錄時的日期顯示出來。
我試過打印cal.Last_Calibration的對象類型,它是Python的日期時間(與zope的我相信?)。 我試圖設置字段等於今天的日期:datetime.today()並得到相同的錯誤。 只是踢,我也嘗試將currentCal.Last_Calibration轉換爲一個字符串,並將其傳遞到字段,雖然這只是隨機數字內的字段。

爲了記錄在案,我進口Python的日期時間爲:

from datetime import datetime 

此外,添加記錄/校準工作正常,所以它不是與數據庫或SQLAlchemy的架構問題,我使用。

如果可能,在updateWidgets函數中設置模式字段值的適當方式是什麼?

我應該使用不同的小工具嗎?如果是這樣,我真正需要的就是日期。添加/更新功能將採用日期時間對象,所以我可以根據數據創建日期時間對象,無論我認爲什麼類型。

+0

不確定,但嘗試使用Zope DateTime(您有方法將本地Python日期時間對象轉換爲這些)。 –

+0

我試圖將python datetime轉換爲zope datetime對象。 self.widgets [「Last_Calibration」]。value = DateTime(currentCal.Last_Calibration)。這給了我一個類型錯誤消息,指出DateTime對象不支持索引。我也試過self.widgets [「Last_Calibration」]。value = DateTime(datetime.today()),但是這給了我同樣的錯誤。 –

+0

編輯:我發現了一些有趣的東西。 schema.DateTime小部件正在查找元組或列表。 它似乎接受的格式是(年,月_as_integer,day_as_integer,小時,分鐘,時區) 因此,例如,這工作: self.widgets [Last_Calibration] .value =(2016,04,05,13,​​04, 'EST') –

回答

3

在z3c.form框架下面的步驟發生,以獲得小部件值:

  1. 如果請求已經有一個值(從以前的表單提交),它被使用。
  2. 如果form.ignoreContext == False(默認),它會調用form.getContent()以獲取表單正在編輯的「內容對象」(默認爲form.context)。
  3. 如果內容對象提供字段來自的模式接口,則「字段值」將作爲對象的屬性提取。 (如果它沒有提供模式接口,z3c.form會在模式接口中查找該對象的適配器,並在適配器上獲取該屬性。如果內容對象是字典,則字段值將作爲一個項目的字典,而不是使用屬性查找。)
  4. 基於字段類型和窗口小部件類型的「轉換器」用於將字段值轉換爲窗口小部件值。區別在於字段值是實際存儲的值,而小部件值是該值的字符串序列化。

您的問題是,您正在嘗試將窗口小部件的值設置爲日期時間,而不是該窗口小部件所期望的日期時間的序列化。

我會做你想要什麼通過重寫的getContent而不是updateWidgets做:

from five import grok 
from plone.directives import form 

class EditCalibration(form.SchemaForm): 
    grok.name('edit-calibration') 
    grok.require('zope2.View') 
    grok.context(ISiteRoot) 

    schema = ICalibration 

    def getContent(self): 
     id = self.request.get('id', None) 
     if id: 
      return session.query(Calibration).filter(Calibration.Calibration_ID == id).one() 

您還需要聲明的是你的校準類實現ICalibration接口,這樣z3c.form承認它可以將Last_Calibration作爲Calibration實例的一個屬性。這看起來應該是這樣的:

from zope.interface import implementer 

@implementer(ICalibration) 
class Calibration(Base): 
    etc... 
+0

非常感謝您的解釋性回覆。我很感激。這工作完美。 –

+0

雖然我在控制檯出現錯誤:TypeError :('Could not adapt,'None,) 我認爲它與我的一個領域是一個Choice,而在我的映射類中,該字段是一個整數。 –

+0

編輯:想出來,有一個錯字。沒有衝突。你的答案是一個非常好的解決方案。我更感興趣的是現在使用form.SchemaForm來做我正在做的事情。這大大減少了代碼量。 –

相關問題