在我正在处理的 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 框架中,以下步骤恰好获取小部件值:
- 如果请求已具有值(来自以前的表单提交),则使用该值。
- 如果 form.ignoreContext == False(默认值),它将调用 form.getContent() 来获取表单正在编辑的"内容对象"(默认为 form.context)。
- 如果内容对象提供了字段来自的架构接口,则"字段值"将作为对象的属性进行提取。(如果它不提供架构接口,z3c.form 将查找对象到架构接口的适配器,并获取适配器上的属性。如果内容对象是字典,则字段值将作为字典的一个项目提取,而不是使用属性查找。 基于字段类型和微件
- 类型的"转换器"用于将字段值转换为微件值。不同之处在于字段值是实际存储的值,而小部件值是该值的字符串序列化。
您的问题是您尝试将小部件值设置为日期时间,而不是小部件期望的该日期时间的序列化。
我会通过覆盖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...