Zope.Schema/Plone - 如何在 updateWidget 函数中设置日期时间字段的值



在我正在处理的 plone 站点上,我有一个表单,用于编辑映射到后端数据库中的表的存储对象的记录。 在接口类中,其中一个字段是架构。日期时间字段。

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

但我收到此错误:

"TypeError: 'datetime.datetime' 对象没有属性 'getitem'。

我确实尝试了一些有趣的事情。我打印了 cal 的值。Last_Calibration,它是我添加唱片时输入的日期。
我尝试打印该 cal 的对象类型。Last_Calibration是,这是 python 的日期时间(我相信与 zope 的日期相反?我尝试将字段设置为等于今天的日期:datetime.today() 并得到同样的错误。只是为了踢球,我还尝试将currentCal.Last_Calibration转换为字符串并将其传递到字段中,尽管这只是将随机数放入字段中。

作为记录,我将python的日期时间导入为:

from datetime import datetime

此外,添加记录/校准工作正常,因此它不是数据库或我正在使用的 sqlalchemy 架构的问题。

如果可能,在 updateWidgets 函数中设置架构字段值的适当方法是什么?

我应该使用其他小部件吗? 如果是这样,我真正需要的只是日期。 add/update 函数将采用一个日期时间对象,因此我可以从数据创建一个日期时间对象,无论我相信哪种类型。

在 z3c.form 框架中,以下步骤恰好获取小部件值:

  1. 如果请求已具有值(来自以前的表单提交),则使用该值。
  2. 如果 form.ignoreContext == False(默认值),它将调用 form.getContent() 来获取表单正在编辑的"内容对象"(默认为 form.context)。
  3. 如果内容对象提供了字段来自的架构接口,则"字段值"将作为对象的属性进行提取。(如果它不提供架构接口,z3c.form 将查找对象到架构接口的适配器,并获取适配器上的属性。如果内容对象是字典,则字段值将作为字典的一个项目提取,而不是使用属性查找。
  4. 基于字段类型和微件
  5. 类型的"转换器"用于将字段值转换为微件值。不同之处在于字段值是实际存储的值,而小部件值是该值的字符串序列化。

您的问题是您尝试将小部件值设置为日期时间,而不是小部件期望的该日期时间的序列化。

我会通过覆盖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。它应该看起来像这样:

from zope.interface import implementer
@implementer(ICalibration)
class Calibration(Base):
    etc...

最新更新